Merge pull request #22017 from vjpai/method_map

Reuse registered call metadata across stubs of the same service on the same channel
pull/22183/head
Vijay Pai 5 years ago committed by GitHub
commit 057f2b6139
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      BUILD
  2. 3
      CMakeLists.txt
  3. 11
      Makefile
  4. 3
      build_autogenerated.yaml
  5. 4
      include/grpc/grpc.h
  6. 4
      include/grpcpp/channel_impl.h
  7. 44
      include/grpcpp/test/channel_test_peer.h
  8. 78
      src/core/lib/surface/channel.cc
  9. 39
      src/core/lib/surface/channel.h
  10. 40
      src/cpp/client/channel_test_peer.cc
  11. 1
      test/cpp/end2end/BUILD
  12. 14
      test/cpp/end2end/end2end_test.cc

@ -2259,12 +2259,16 @@ grpc_cc_library(
grpc_cc_library(
name = "grpc++_test",
srcs = [
"src/cpp/client/channel_test_peer.cc",
],
public_hdrs = [
"include/grpc++/test/mock_stream.h",
"include/grpc++/test/server_context_test_spouse.h",
"include/grpcpp/test/channel_test_peer.h",
"include/grpcpp/test/default_reactor_test_peer.h",
"include/grpcpp/test/mock_stream.h",
"include/grpcpp/test/server_context_test_spouse.h",
"include/grpcpp/test/default_reactor_test_peer.h",
],
deps = [
":grpc++",

@ -10217,6 +10217,7 @@ add_executable(end2end_test
${_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
src/cpp/client/channel_test_peer.cc
test/cpp/end2end/end2end_test.cc
test/cpp/end2end/interceptors_util.cc
test/cpp/end2end/test_service_impl.cc
@ -11903,6 +11904,7 @@ add_executable(mock_test
${_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
src/cpp/client/channel_test_peer.cc
test/cpp/end2end/mock_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
@ -12879,6 +12881,7 @@ endif()
if(gRPC_BUILD_TESTS)
add_executable(server_context_test_spouse_test
src/cpp/client/channel_test_peer.cc
test/cpp/test/server_context_test_spouse_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc

@ -13870,6 +13870,7 @@ END2END_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \
src/cpp/client/channel_test_peer.cc \
test/cpp/end2end/end2end_test.cc \
test/cpp/end2end/interceptors_util.cc \
test/cpp/end2end/test_service_impl.cc \
@ -13911,6 +13912,8 @@ $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/simple_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)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_test_peer.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)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
@ -13924,6 +13927,7 @@ ifneq ($(NO_DEPS),true)
-include $(END2END_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_test_peer.o: $(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/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/end2end_test.o: $(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/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(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/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/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/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.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/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
@ -15866,6 +15870,7 @@ MOCK_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \
src/cpp/client/channel_test_peer.cc \
test/cpp/end2end/mock_test.cc \
MOCK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MOCK_TEST_SRC))))
@ -15905,6 +15910,8 @@ $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/simple_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)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_test_peer.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)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.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 $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
deps_mock_test: $(MOCK_TEST_OBJS:.o=.dep)
@ -15914,6 +15921,7 @@ ifneq ($(NO_DEPS),true)
-include $(MOCK_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_test_peer.o: $(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/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_test.o: $(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/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.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/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
@ -17168,6 +17176,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $
SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
src/cpp/client/channel_test_peer.cc \
test/cpp/test/server_context_test_spouse_test.cc \
SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC))))
@ -17199,6 +17208,8 @@ endif
endif
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_test_peer.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)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_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)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
deps_server_context_test_spouse_test: $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep)

@ -5638,6 +5638,7 @@ targets:
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/simple_messages.proto
- src/cpp/client/channel_test_peer.cc
- test/cpp/end2end/end2end_test.cc
- test/cpp/end2end/interceptors_util.cc
- test/cpp/end2end/test_service_impl.cc
@ -6344,6 +6345,7 @@ targets:
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/simple_messages.proto
- src/cpp/client/channel_test_peer.cc
- test/cpp/end2end/mock_test.cc
deps:
- grpc++_test_util
@ -6807,6 +6809,7 @@ targets:
language: c++
headers: []
src:
- src/cpp/client/channel_test_peer.cc
- test/cpp/test/server_context_test_spouse_test.cc
deps:
- grpc++_test_util

@ -225,8 +225,8 @@ GRPCAPI void grpc_channel_ping(grpc_channel* channel, grpc_completion_queue* cq,
void* tag, void* reserved);
/** Pre-register a method/host pair on a channel.
method and host are not owned and must remain alive while the server is
running. */
method and host are not owned and must remain alive while the channel is
alive. */
GRPCAPI void* grpc_channel_register_call(grpc_channel* channel,
const char* method, const char* host,
void* reserved);

@ -33,6 +33,9 @@
struct grpc_channel;
namespace grpc {
namespace testing {
class ChannelTestPeer;
} // namespace testing
std::shared_ptr<::grpc_impl::Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
@ -71,6 +74,7 @@ class Channel final : public ::grpc::ChannelInterface,
private:
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
friend class ::grpc::testing::ChannelTestPeer;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> grpc::CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,

@ -0,0 +1,44 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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_TEST_CHANNEL_TEST_PEER_H
#define GRPCPP_TEST_CHANNEL_TEST_PEER_H
#include <grpcpp/channel.h>
namespace grpc {
namespace testing {
/// A test-only class to access private members of Channel.
class ChannelTestPeer {
public:
explicit ChannelTestPeer(Channel* channel) : channel_(channel) {}
/// Provide the gRPC Core channel
grpc_channel* channel() const { return channel_->c_channel_; }
int registered_calls() const;
int registration_attempts() const;
private:
Channel* channel_; // not owned
};
} // namespace testing
} // namespace grpc
#endif // GRPCPP_TEST_CHANNEL_TEST_PEER_H

@ -54,12 +54,6 @@
* (OK, Cancelled, Unknown). */
#define NUM_CACHED_STATUS_ELEMS 3
typedef struct registered_call {
grpc_mdelem path;
grpc_mdelem authority;
struct registered_call* next;
} registered_call;
static void destroy_channel(void* arg, grpc_error* error);
grpc_channel* grpc_channel_create_with_builder(
@ -90,8 +84,7 @@ grpc_channel* grpc_channel_create_with_builder(
channel->target = target;
channel->resource_user = resource_user;
channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = nullptr;
channel->registration_table.Init();
gpr_atm_no_barrier_store(
&channel->call_size_estimate,
@ -417,35 +410,65 @@ grpc_call* grpc_channel_create_pollset_set_call(
deadline);
}
namespace grpc_core {
RegisteredCall::RegisteredCall(const char* method, const char* host) {
path = grpc_mdelem_from_slices(GRPC_MDSTR_PATH,
grpc_core::ExternallyManagedSlice(method));
authority =
host ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_core::ExternallyManagedSlice(host))
: GRPC_MDNULL;
}
// TODO(vjpai): Delete copy-constructor when allowed by all supported compilers.
RegisteredCall::RegisteredCall(const RegisteredCall& other) {
path = other.path;
authority = other.authority;
GRPC_MDELEM_REF(path);
GRPC_MDELEM_REF(authority);
}
RegisteredCall::RegisteredCall(RegisteredCall&& other) {
path = other.path;
authority = other.authority;
other.path = GRPC_MDNULL;
other.authority = GRPC_MDNULL;
}
RegisteredCall::~RegisteredCall() {
GRPC_MDELEM_UNREF(path);
GRPC_MDELEM_UNREF(authority);
}
} // namespace grpc_core
void* grpc_channel_register_call(grpc_channel* channel, const char* method,
const char* host, void* reserved) {
registered_call* rc =
static_cast<registered_call*>(gpr_malloc(sizeof(registered_call)));
GRPC_API_TRACE(
"grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
4, (channel, method, host, reserved));
GPR_ASSERT(!reserved);
grpc_core::ExecCtx exec_ctx;
rc->path = grpc_mdelem_from_slices(GRPC_MDSTR_PATH,
grpc_core::ExternallyManagedSlice(method));
rc->authority =
host ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_core::ExternallyManagedSlice(host))
: GRPC_MDNULL;
gpr_mu_lock(&channel->registered_call_mu);
rc->next = channel->registered_calls;
channel->registered_calls = rc;
gpr_mu_unlock(&channel->registered_call_mu);
return rc;
grpc_core::MutexLock lock(&channel->registration_table->mu);
channel->registration_table->method_registration_attempts++;
auto key = std::make_pair(host, method);
auto rc_posn = channel->registration_table->map.find(key);
if (rc_posn != channel->registration_table->map.end()) {
return &rc_posn->second;
}
auto insertion_result = channel->registration_table->map.insert(
{key, grpc_core::RegisteredCall(method, host)});
return &insertion_result.first->second;
}
grpc_call* grpc_channel_create_registered_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* completion_queue, void* registered_call_handle,
gpr_timespec deadline, void* reserved) {
registered_call* rc = static_cast<registered_call*>(registered_call_handle);
grpc_core::RegisteredCall* rc =
static_cast<grpc_core::RegisteredCall*>(registered_call_handle);
GRPC_API_TRACE(
"grpc_channel_create_registered_call("
"channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, "
@ -486,18 +509,11 @@ static void destroy_channel(void* arg, grpc_error* /*error*/) {
channel->channelz_node.reset();
}
grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
while (channel->registered_calls) {
registered_call* rc = channel->registered_calls;
channel->registered_calls = rc->next;
GRPC_MDELEM_UNREF(rc->path);
GRPC_MDELEM_UNREF(rc->authority);
gpr_free(rc);
}
channel->registration_table.Destroy();
if (channel->resource_user != nullptr) {
grpc_resource_user_free(channel->resource_user,
GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
}
gpr_mu_destroy(&channel->registered_call_mu);
gpr_free(channel->target);
gpr_free(channel);
// See comment in grpc_channel_create() for why we do this.

@ -21,10 +21,14 @@
#include <grpc/support/port_platform.h>
#include <map>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/transport/metadata.h"
grpc_channel* grpc_channel_create(const char* target,
const grpc_channel_args* args,
@ -62,7 +66,30 @@ grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node(
size_t grpc_channel_get_call_size_estimate(grpc_channel* channel);
void grpc_channel_update_call_size_estimate(grpc_channel* channel, size_t size);
struct registered_call;
namespace grpc_core {
struct RegisteredCall {
grpc_mdelem path;
grpc_mdelem authority;
explicit RegisteredCall(const char* method, const char* host);
// TODO(vjpai): delete copy constructor once all supported compilers allow
// std::map value_type to be MoveConstructible.
RegisteredCall(const RegisteredCall& other);
RegisteredCall(RegisteredCall&& other);
~RegisteredCall();
};
struct CallRegistrationTable {
grpc_core::Mutex mu;
std::map<std::pair<const char*, const char*>, RegisteredCall>
map /* GUARDED_BY(mu) */;
int method_registration_attempts /* GUARDED_BY(mu) */ = 0;
};
} // namespace grpc_core
struct grpc_channel {
int is_client;
grpc_compression_options compression_options;
@ -70,9 +97,13 @@ struct grpc_channel {
gpr_atm call_size_estimate;
grpc_resource_user* resource_user;
gpr_mu registered_call_mu;
registered_call* registered_calls;
// TODO(vjpai): Once the grpc_channel is allocated via new rather than malloc,
// expand the members of the CallRegistrationTable directly into
// the grpc_channel. For now it is kept separate so that all the
// manual constructing can be done with a single call rather than
// a separate manual construction for each field.
grpc_core::ManualConstructor<grpc_core::CallRegistrationTable>
registration_table;
grpc_core::RefCountedPtr<grpc_core::channelz::ChannelNode> channelz_node;
char* target;

@ -0,0 +1,40 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <grpcpp/test/channel_test_peer.h>
#include <grpc/support/sync.h>
#include <grpcpp/channel.h>
#include "src/core/lib/surface/channel.h"
namespace grpc {
namespace testing {
int ChannelTestPeer::registered_calls() const {
grpc_core::MutexLock lock(&channel_->c_channel_->registration_table->mu);
return static_cast<int>(channel_->c_channel_->registration_table->map.size());
}
int ChannelTestPeer::registration_attempts() const {
grpc_core::MutexLock lock(&channel_->c_channel_->registration_table->mu);
return channel_->c_channel_->registration_table->method_registration_attempts;
}
} // namespace testing
} // namespace grpc

@ -225,6 +225,7 @@ grpc_cc_library(
"//:gpr",
"//:grpc",
"//:grpc++",
"//:grpc++_test",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto",

@ -31,6 +31,7 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
#include <grpcpp/test/channel_test_peer.h>
#include <mutex>
#include <thread>
@ -812,6 +813,19 @@ TEST_P(End2endTest, MultipleRpcs) {
}
}
TEST_P(End2endTest, ManyStubs) {
MAYBE_SKIP_TEST;
ResetStub();
ChannelTestPeer peer(channel_.get());
int registered_calls_pre = peer.registered_calls();
int registration_attempts_pre = peer.registration_attempts();
for (int i = 0; i < 1000; ++i) {
grpc::testing::EchoTestService::NewStub(channel_);
}
EXPECT_EQ(peer.registered_calls(), registered_calls_pre);
EXPECT_GT(peer.registration_attempts(), registration_attempts_pre);
}
TEST_P(End2endTest, EmptyBinaryMetadata) {
MAYBE_SKIP_TEST;
ResetStub();

Loading…
Cancel
Save