diff --git a/.gitmodules b/.gitmodules index afde4d34f36..06f1394df65 100644 --- a/.gitmodules +++ b/.gitmodules @@ -42,3 +42,15 @@ path = third_party/libcxx url = https://github.com/llvm-mirror/libcxx.git branch = release_60 +[submodule "third_party/data-plane-api"] + path = third_party/data-plane-api + url = https://github.com/envoyproxy/data-plane-api.git +[submodule "third_party/googleapis"] + path = third_party/googleapis + 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 +[submodule "third_party/upb"] + path = third_party/upb + url = https://github.com/google/upb.git 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/BUILD b/BUILD index e86e48c7e33..9a2c16c6012 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 = "6.0.0-dev" +core_version = "7.0.0-dev" -version = "1.17.0-dev" +version = "1.18.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", @@ -647,6 +647,7 @@ grpc_cc_library( "debug_location", "gpr_base", "grpc_trace", + "ref_counted", "ref_counted_ptr", ], ) @@ -1048,12 +1049,12 @@ grpc_cc_library( "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/method_params.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", "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/retry_throttle.cc", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel_index.cc", @@ -1070,13 +1071,13 @@ grpc_cc_library( "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/method_params.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", "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/retry_throttle.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_index.h", @@ -1650,6 +1651,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", @@ -1673,6 +1675,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", @@ -1962,7 +1965,6 @@ grpc_cc_library( "src/core/tsi/alts/handshaker/alts_shared_resource.cc", "src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc", "src/core/tsi/alts/handshaker/alts_tsi_utils.cc", - "src/core/tsi/alts_transport_security.cc", "src/core/tsi/fake_transport_security.cc", "src/core/tsi/local_transport_security.cc", "src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc", @@ -1977,7 +1979,6 @@ grpc_cc_library( "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.h", - "src/core/tsi/alts_transport_security.h", "src/core/tsi/fake_transport_security.h", "src/core/tsi/local_transport_security.h", "src/core/tsi/ssl/session_cache/ssl_session.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c9c6a02fe..23b4bb77e75 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/") @@ -588,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) @@ -1132,6 +1133,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 @@ -1240,18 +1242,17 @@ add_library(grpc 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/method_params.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 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/retry_throttle.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 src/core/ext/filters/client_channel/health/health.pb.c - src/core/tsi/alts_transport_security.cc src/core/tsi/fake_transport_security.cc src/core/tsi/local_transport_security.cc src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc @@ -1556,6 +1557,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 @@ -1592,12 +1594,12 @@ add_library(grpc_cronet 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/method_params.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 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/retry_throttle.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc @@ -1675,7 +1677,6 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc src/core/ext/transport/chttp2/client/authority.cc src/core/ext/transport/chttp2/client/chttp2_connector.cc - src/core/tsi/alts_transport_security.cc src/core/tsi/fake_transport_security.cc src/core/tsi/local_transport_security.cc src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc @@ -1964,12 +1965,12 @@ add_library(grpc_test_util 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/method_params.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 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/retry_throttle.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc @@ -1982,6 +1983,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 @@ -2283,12 +2285,12 @@ add_library(grpc_test_util_unsecure 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/method_params.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 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/retry_throttle.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc @@ -2301,6 +2303,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 @@ -2574,6 +2577,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 @@ -2615,12 +2619,12 @@ add_library(grpc_unsecure 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/method_params.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 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/retry_throttle.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc @@ -3278,6 +3282,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 @@ -3466,12 +3471,12 @@ add_library(grpc++_cronet 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/method_params.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 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/retry_throttle.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc @@ -12700,6 +12705,45 @@ 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 + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) 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. diff --git a/Makefile b/Makefile index ca881ab0e14..4f7cd130120 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) @@ -1168,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 @@ -1673,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 \ @@ -1856,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 \ @@ -2320,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" @@ -3064,7 +3069,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -3073,7 +3078,7 @@ endif ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -3082,7 +3087,7 @@ endif ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_error_details.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -3091,7 +3096,7 @@ endif ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -3100,7 +3105,7 @@ endif ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -3109,7 +3114,7 @@ endif ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpcpp_channelz.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so endif ifneq ($(SYSTEM),MINGW32) @@ -3126,7 +3131,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.7 + $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so endif ifneq ($(SYSTEM),MINGW32) @@ -3607,6 +3612,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 \ @@ -3715,18 +3721,17 @@ LIBGRPC_SRC = \ 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/method_params.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 \ 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/retry_throttle.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 \ src/core/ext/filters/client_channel/health/health.pb.c \ - src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \ @@ -4025,6 +4030,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 \ @@ -4061,12 +4067,12 @@ LIBGRPC_CRONET_SRC = \ 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/method_params.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 \ 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/retry_throttle.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ @@ -4144,7 +4150,6 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \ src/core/ext/transport/chttp2/client/authority.cc \ src/core/ext/transport/chttp2/client/chttp2_connector.cc \ - src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \ @@ -4426,12 +4431,12 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/method_params.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 \ 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/retry_throttle.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ @@ -4444,6 +4449,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 \ @@ -4731,12 +4737,12 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/method_params.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 \ 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/retry_throttle.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ @@ -4749,6 +4755,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 \ @@ -4995,6 +5002,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 \ @@ -5036,12 +5044,12 @@ LIBGRPC_UNSECURE_SRC = \ 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/method_params.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 \ 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/retry_throttle.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ @@ -5674,6 +5682,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 \ @@ -5862,12 +5871,12 @@ LIBGRPC++_CRONET_SRC = \ 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/method_params.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 \ 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/retry_throttle.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ @@ -17550,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 $(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 $(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 $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.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 \ @@ -25037,7 +25089,6 @@ src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_p src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc: $(OPENSSL_DEP) src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc: $(OPENSSL_DEP) src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc: $(OPENSSL_DEP) -src/core/tsi/alts_transport_security.cc: $(OPENSSL_DEP) src/core/tsi/fake_transport_security.cc: $(OPENSSL_DEP) src/core/tsi/local_transport_security.cc: $(OPENSSL_DEP) src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc: $(OPENSSL_DEP) diff --git a/README.md b/README.md index 1960f44137c..b3a4c1f17d1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ gRPC - An RPC library and framework =================================== -gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems. +gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. gRPC enables client and server applications to communicate transparently, and simplifies the building of connected systems. @@ -18,10 +18,10 @@ gRPC is a modern, open source, high-performance remote procedure call (RPC) fram # To start using gRPC -To maximize usability, gRPC supports the standard way of adding dependencies in your language of choice (if there is one). -In most languages, the gRPC runtime comes in form of a package available in your language's package manager. +To maximize usability, gRPC supports the standard method for adding dependencies to a user's chosen language (if there is one). +In most languages, the gRPC runtime comes as a package available in a user's language package manager. -For instructions on how to use the language-specific gRPC runtime in your project, please refer to these documents +For instructions on how to use the language-specific gRPC runtime for a project, please refer to these documents * [C++](src/cpp): follow the instructions under the `src/cpp` directory * [C#](src/csharp): NuGet package `Grpc` @@ -35,7 +35,7 @@ For instructions on how to use the language-specific gRPC runtime in your projec * [Ruby](src/ruby): `gem install grpc` * [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions -You can find per-language quickstart guides and tutorials in [Documentation section on grpc.io website](https://grpc.io/docs/). The code examples are available in the [examples](examples) directory. +Per-language quickstart guides and tutorials can be found in the [documentation section on the grpc.io website](https://grpc.io/docs/). Code examples are available in the [examples](examples) directory. Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are uploaded daily to [packages.grpc.io](https://packages.grpc.io). @@ -43,9 +43,9 @@ Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are up Contributions are welcome! -Please read [How to contribute](CONTRIBUTING.md) which will guide you through the entire workflow of how to build the source code, how to run the tests and how to contribute your changes to +Please read [How to contribute](CONTRIBUTING.md) which will guide you through the entire workflow of how to build the source code, how to run the tests, and how to contribute changes to the gRPC codebase. -The document also contains info on how the contributing process works and contains best practices for creating contributions. +The "How to contribute" document also contains info on how the contribution process works and contains best practices for creating contributions. # Troubleshooting @@ -53,7 +53,7 @@ Sometimes things go wrong. Please check out the [Troubleshooting guide](TROUBLES # Performance -See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for the performance numbers for the latest released version. +See the [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for performance numbers of the latest released version. # Concepts @@ -61,9 +61,9 @@ See [gRPC Concepts](CONCEPTS.md) # About This Repository -This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core](src/core). +This repository contains source code for gRPC libraries implemented in multiple languages written on top of a shared C core library [src/core](src/core). -Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries. +Libraries in different languages may be in various states of development. We are seeking contributions for all of these libraries: | Language | Source | |-------------------------|-------------------------------------| diff --git a/WORKSPACE b/WORKSPACE index c1e63d86e50..8d0fd693c6c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,47 +1,60 @@ -workspace(name="com_github_grpc_grpc") +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() +register_execution_platforms( + "//third_party/toolchains:all", +) + +register_toolchains( + "//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() diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 159ebd5d1fe..65fe5a10aa2 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) @@ -162,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) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 82aada24629..3eacd2b0475 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -11,6 +11,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", @@ -187,6 +192,13 @@ def grpc_deps(): url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", ) + 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", + ) + # TODO: move some dependencies from "grpc_deps" here? def grpc_test_only_deps(): diff --git a/build.yaml b/build.yaml index 9090a80b6a7..381e649b392 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: @@ -580,13 +580,13 @@ filegroups: - 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/method_params.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 - 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/retry_throttle.h - src/core/ext/filters/client_channel/subchannel.h - src/core/ext/filters/client_channel/subchannel_index.h @@ -604,12 +604,12 @@ filegroups: - 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/method_params.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 - 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/retry_throttle.cc - src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc @@ -962,6 +962,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 @@ -984,6 +985,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 @@ -1146,7 +1148,6 @@ filegroups: - grpc - name: tsi headers: - - src/core/tsi/alts_transport_security.h - src/core/tsi/fake_transport_security.h - src/core/tsi/local_transport_security.h - src/core/tsi/ssl/session_cache/ssl_session.h @@ -1155,7 +1156,6 @@ filegroups: - src/core/tsi/ssl_types.h - src/core/tsi/transport_security_grpc.h src: - - src/core/tsi/alts_transport_security.cc - src/core/tsi/fake_transport_security.cc - src/core/tsi/local_transport_security.cc - src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc @@ -1165,7 +1165,6 @@ filegroups: - src/core/tsi/transport_security_grpc.cc deps: - gpr - plugin: grpc_tsi_alts secure: true uses: - tsi_interface @@ -4489,6 +4488,7 @@ targets: - gpr - name: client_channel_stress_test gtest: false + cpu_cost: 10.0 build: test language: c++ src: @@ -4604,6 +4604,18 @@ targets: - grpc++_codegen_base - grpc++_codegen_base_src uses_polling: false +- name: context_list_test + gtest: true + build: test + language: c++ + src: + - test/core/transport/chttp2/context_list_test.cc + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + uses_polling: false - name: credentials_test gtest: true build: test diff --git a/config.m4 b/config.m4 index 15f3a543217..3db660aceea 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 \ @@ -349,18 +350,17 @@ if test "$PHP_GRPC" != "no"; then 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/method_params.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 \ 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/retry_throttle.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 \ src/core/ext/filters/client_channel/health/health.pb.c \ - src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \ @@ -665,7 +665,8 @@ if test "$PHP_GRPC" != "no"; then third_party/boringssl/third_party/fiat/curve25519.c \ , $ext_shared, , -fvisibility=hidden \ -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN \ - -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0) + -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 \ + -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1) PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) diff --git a/config.w32 b/config.w32 index 8dff1229bec..7f8b6eee5fa 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 " + @@ -324,18 +325,17 @@ if (PHP_GRPC != "no") { "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\\method_params.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 " + "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\\retry_throttle.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 " + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + - "src\\core\\tsi\\alts_transport_security.cc " + "src\\core\\tsi\\fake_transport_security.cc " + "src\\core\\tsi\\local_transport_security.cc " + "src\\core\\tsi\\ssl\\session_cache\\ssl_session_boringssl.cc " + 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) 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 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/api.rst b/doc/python/sphinx/grpc.rst similarity index 71% rename from doc/python/sphinx/api.rst rename to doc/python/sphinx/grpc.rst index 425504fb28a..bd2df9596b0 100644 --- a/doc/python/sphinx/api.rst +++ b/doc/python/sphinx/grpc.rst @@ -1,10 +1,26 @@ -API Reference +gRPC ============= .. module:: grpc +Tutorial +-------- + +If you want to see gRPC in action first, visit the `Python Quickstart `_. +Or, if you would like dive in with more extensive usage of gRPC Python, check `gRPC Basics - Python `_ out. + + +Example +------- + +Go to `gRPC Python Examples `_ + + +Module Contents +--------------- + Create Client -------------- +^^^^^^^^^^^^^ .. autofunction:: insecure_channel .. autofunction:: secure_channel @@ -12,7 +28,7 @@ Create Client Create Client Credentials -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ .. autofunction:: ssl_channel_credentials .. autofunction:: metadata_call_credentials @@ -22,13 +38,13 @@ Create Client Credentials Create Server -------------- +^^^^^^^^^^^^^ .. autofunction:: server Create Server Credentials -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ .. autofunction:: ssl_server_credentials .. autofunction:: ssl_server_certificate_configuration @@ -36,7 +52,7 @@ Create Server Credentials RPC Method Handlers --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autofunction:: unary_unary_rpc_method_handler .. autofunction:: unary_stream_rpc_method_handler @@ -46,37 +62,37 @@ RPC Method Handlers Channel Ready Future --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autofunction:: channel_ready_future Channel Connectivity --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: ChannelConnectivity gRPC Status Code --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: StatusCode Channel Object --------------- +^^^^^^^^^^^^^^ .. autoclass:: Channel Server Object -------------- +^^^^^^^^^^^^^ .. autoclass:: Server Authentication & Authorization Objects --------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: ChannelCredentials .. autoclass:: CallCredentials @@ -88,25 +104,25 @@ Authentication & Authorization Objects gRPC Exceptions ---------------- +^^^^^^^^^^^^^^^ .. autoexception:: RpcError Shared Context --------------- +^^^^^^^^^^^^^^ .. autoclass:: RpcContext Client-Side Context ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: Call Client-Side Interceptor ------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: ClientCallDetails .. autoclass:: UnaryUnaryClientInterceptor @@ -116,13 +132,13 @@ Client-Side Interceptor Service-Side Context --------------------- +^^^^^^^^^^^^^^^^^^^^ .. autoclass:: ServicerContext Service-Side Handler -------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: RpcMethodHandler .. autoclass:: HandlerCallDetails @@ -131,13 +147,13 @@ Service-Side Handler Service-Side Interceptor ------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: ServerInterceptor -Multi-Callable -------------------------- +Multi-Callable Interfaces +^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: UnaryUnaryMultiCallable .. autoclass:: UnaryStreamMultiCallable @@ -145,8 +161,8 @@ Multi-Callable .. autoclass:: StreamStreamMultiCallable -Future ----------------- +Future Interfaces +^^^^^^^^^^^^^^^^^ .. autoexception:: FutureTimeoutError .. autoexception:: FutureCancelledError 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 b602b2934fe..2f8a47a0747 100644 --- a/doc/python/sphinx/index.rst +++ b/doc/python/sphinx/index.rst @@ -9,7 +9,8 @@ API Reference .. toctree:: :caption: Contents: - api + grpc + grpc_channelz grpc_health_checking grpc_reflection grpc_testing diff --git a/examples/objective-c/helloworld_macos/HelloWorld.podspec b/examples/objective-c/helloworld_macos/HelloWorld.podspec new file mode 100644 index 00000000000..fc671ef4da2 --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld.podspec @@ -0,0 +1,66 @@ +Pod::Spec.new do |s| + s.name = "HelloWorld" + s.version = "0.0.1" + s.license = "Apache License, Version 2.0" + s.authors = { 'gRPC contributors' => 'grpc-io@googlegroups.com' } + s.homepage = "https://grpc.io/" + s.summary = "HelloWorld example" + s.source = { :git => 'https://github.com/grpc/grpc.git' } + + s.ios.deployment_target = "7.1" + s.osx.deployment_target = "10.9" + + # Base directory where the .proto files are. + src = "../../protos" + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" + + # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. + pods_root = 'Pods' + + # Path where Cocoapods downloads protoc and the gRPC plugin. + protoc_dir = "#{pods_root}/!ProtoCompiler" + protoc = "#{protoc_dir}/protoc" + plugin = "#{pods_root}/!ProtoCompiler-gRPCPlugin/grpc_objective_c_plugin" + + # Directory where the generated files will be placed. + dir = "#{pods_root}/#{s.name}" + + s.prepare_command = <<-CMD + mkdir -p #{dir} + #{protoc} \ + --plugin=protoc-gen-grpc=#{plugin} \ + --objc_out=#{dir} \ + --grpc_out=#{dir} \ + -I #{src} \ + -I #{protoc_dir} \ + #{src}/helloworld.proto + CMD + + # Files generated by protoc + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + # The generated files depend on the protobuf runtime. + ms.dependency "Protobuf" + end + + # Files generated by the gRPC plugin + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + # The generated files depend on the gRPC runtime, and on the files generated by protoc. + ss.dependency "gRPC-ProtoRPC" + ss.dependency "#{s.name}/Messages" + end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } +end diff --git a/examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..06f06290d58 --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj @@ -0,0 +1,399 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 5EF711A4215174880077496F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF711A3215174880077496F /* AppDelegate.m */; }; + 5EF711A7215174880077496F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF711A6215174880077496F /* ViewController.m */; }; + 5EF711A9215174890077496F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5EF711A8215174890077496F /* Assets.xcassets */; }; + 5EF711AC215174890077496F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EF711AA215174890077496F /* Main.storyboard */; }; + 5EF711AF215174890077496F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF711AE215174890077496F /* main.m */; }; + 827B966E84F6A63FD0F3F6BC /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 369D887F6054EBA486218C69 /* libPods-HelloWorld.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2AAF8E8BA7DBFD2D3886AA25 /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; + 369D887F6054EBA486218C69 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EF7119F215174870077496F /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EF711A2215174880077496F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5EF711A3215174880077496F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5EF711A5215174880077496F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5EF711A6215174880077496F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5EF711A8215174890077496F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5EF711AB215174890077496F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5EF711AD215174890077496F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EF711AE215174890077496F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5EF711B0215174890077496F /* HelloWorld.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HelloWorld.entitlements; sourceTree = ""; }; + CA4699782F6344C8E67C9FEE /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5EF7119C215174870077496F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 827B966E84F6A63FD0F3F6BC /* libPods-HelloWorld.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5EF71196215174870077496F = { + isa = PBXGroup; + children = ( + 5EF711AE215174890077496F /* main.m */, + 5EF711A1215174870077496F /* HelloWorld */, + 5EF711A0215174870077496F /* Products */, + 8D3EFBB796129582177142C4 /* Pods */, + A986548CB5622AF6CC3ECCCE /* Frameworks */, + ); + sourceTree = ""; + }; + 5EF711A0215174870077496F /* Products */ = { + isa = PBXGroup; + children = ( + 5EF7119F215174870077496F /* HelloWorld.app */, + ); + name = Products; + sourceTree = ""; + }; + 5EF711A1215174870077496F /* HelloWorld */ = { + isa = PBXGroup; + children = ( + 5EF711A2215174880077496F /* AppDelegate.h */, + 5EF711A3215174880077496F /* AppDelegate.m */, + 5EF711A5215174880077496F /* ViewController.h */, + 5EF711A6215174880077496F /* ViewController.m */, + 5EF711A8215174890077496F /* Assets.xcassets */, + 5EF711AA215174890077496F /* Main.storyboard */, + 5EF711AD215174890077496F /* Info.plist */, + 5EF711B0215174890077496F /* HelloWorld.entitlements */, + ); + path = HelloWorld; + sourceTree = ""; + }; + 8D3EFBB796129582177142C4 /* Pods */ = { + isa = PBXGroup; + children = ( + CA4699782F6344C8E67C9FEE /* Pods-HelloWorld.debug.xcconfig */, + 2AAF8E8BA7DBFD2D3886AA25 /* Pods-HelloWorld.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + A986548CB5622AF6CC3ECCCE /* Frameworks */ = { + isa = PBXGroup; + children = ( + 369D887F6054EBA486218C69 /* libPods-HelloWorld.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5EF7119E215174870077496F /* HelloWorld */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EF711B3215174890077496F /* Build configuration list for PBXNativeTarget "HelloWorld" */; + buildPhases = ( + 3694AEA482289A5BDD5EA5A4 /* [CP] Check Pods Manifest.lock */, + 5EF7119B215174870077496F /* Sources */, + 5EF7119C215174870077496F /* Frameworks */, + 5EF7119D215174870077496F /* Resources */, + DF5241368CCEAA9DC73E7EA8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HelloWorld; + productName = HelloWorld; + productReference = 5EF7119F215174870077496F /* HelloWorld.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5EF71197215174870077496F /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5EF7119E215174870077496F = { + CreatedOnToolsVersion = 9.3; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 0; + }; + }; + }; + }; + }; + buildConfigurationList = 5EF7119A215174870077496F /* Build configuration list for PBXProject "HelloWorld" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5EF71196215174870077496F; + productRefGroup = 5EF711A0215174870077496F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5EF7119E215174870077496F /* HelloWorld */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5EF7119D215174870077496F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EF711A9215174890077496F /* Assets.xcassets in Resources */, + 5EF711AC215174890077496F /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3694AEA482289A5BDD5EA5A4 /* [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-HelloWorld-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; + }; + DF5241368CCEAA9DC73E7EA8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-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-HelloWorld/Pods-HelloWorld-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5EF7119B215174870077496F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EF711A7215174880077496F /* ViewController.m in Sources */, + 5EF711AF215174890077496F /* main.m in Sources */, + 5EF711A4215174880077496F /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5EF711AA215174890077496F /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5EF711AB215174890077496F /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5EF711B1215174890077496F /* 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 = "-"; + 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; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 5EF711B2215174890077496F /* 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 = "-"; + 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; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 5EF711B4215174890077496F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CA4699782F6344C8E67C9FEE /* Pods-HelloWorld.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = HelloWorld/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.HelloWorld; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5EF711B5215174890077496F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2AAF8E8BA7DBFD2D3886AA25 /* Pods-HelloWorld.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = HelloWorld/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.HelloWorld; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5EF7119A215174870077496F /* Build configuration list for PBXProject "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EF711B1215174890077496F /* Debug */, + 5EF711B2215174890077496F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EF711B3215174890077496F /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EF711B4215174890077496F /* Debug */, + 5EF711B5215174890077496F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5EF71197215174870077496F /* Project object */; +} diff --git a/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.h b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.h new file mode 100644 index 00000000000..1b88e35d22d --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.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 + +@interface AppDelegate : NSObject + + +@end + diff --git a/src/core/tsi/alts_transport_security.cc b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.m similarity index 51% rename from src/core/tsi/alts_transport_security.cc rename to examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.m index 5a1494ae5c1..7da5e1171b3 100644 --- a/src/core/tsi/alts_transport_security.cc +++ b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.m @@ -1,6 +1,6 @@ /* * - * Copyright 2017 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,26 +16,22 @@ * */ -#include +#import "AppDelegate.h" -#include +@interface AppDelegate () -#include "src/core/tsi/alts_transport_security.h" +@end -static alts_shared_resource g_alts_resource; +@implementation AppDelegate -alts_shared_resource* alts_get_shared_resource(void) { - return &g_alts_resource; +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application } -void grpc_tsi_alts_init() { - g_alts_resource.channel = nullptr; - gpr_mu_init(&g_alts_resource.mu); -} -void grpc_tsi_alts_shutdown() { - if (g_alts_resource.channel != nullptr) { - grpc_channel_destroy(g_alts_resource.channel); - } - gpr_mu_destroy(&g_alts_resource.mu); +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application } + + +@end diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..2db2b1c7c6c --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json new file mode 100644 index 00000000000..da4a164c918 --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard b/examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard new file mode 100644 index 00000000000..3ed4144fba4 --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard @@ -0,0 +1,717 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements b/examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements new file mode 100644 index 00000000000..0c67376ebac --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Info.plist b/examples/objective-c/helloworld_macos/HelloWorld/Info.plist new file mode 100644 index 00000000000..f7bfdac9d6f --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2018 gRPC. All rights reserved. + NSMainStoryboardFile + Main + NSPrincipalClass + NSApplication + + diff --git a/examples/objective-c/helloworld_macos/HelloWorld/ViewController.h b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.h new file mode 100644 index 00000000000..ff620dc4267 --- /dev/null +++ b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.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 + +@interface ViewController : NSViewController + + +@end + diff --git a/src/core/tsi/alts_transport_security.h b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.m similarity index 50% rename from src/core/tsi/alts_transport_security.h rename to examples/objective-c/helloworld_macos/HelloWorld/ViewController.m index f4319d10d23..fc9e95f9a6e 100644 --- a/src/core/tsi/alts_transport_security.h +++ b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.m @@ -1,6 +1,6 @@ /* * - * Copyright 2017 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,23 +16,22 @@ * */ -#ifndef GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H +#import "ViewController.h" -#include +@implementation ViewController -#include -#include +- (void)viewDidLoad { + [super viewDidLoad]; -#include "src/core/lib/gprpp/thd.h" + // Do any additional setup after loading the view. +} -typedef struct alts_shared_resource { - grpc_channel* channel; - gpr_mu mu; -} alts_shared_resource; -/* This method returns the address of alts_shared_resource object shared by all - * TSI handshakes. */ -alts_shared_resource* alts_get_shared_resource(void); +- (void)setRepresentedObject:(id)representedObject { + [super setRepresentedObject:representedObject]; -#endif /* GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H */ + // Update the view, if already loaded. +} + + +@end diff --git a/examples/objective-c/helloworld_macos/Podfile b/examples/objective-c/helloworld_macos/Podfile new file mode 100644 index 00000000000..bf1488cba64 --- /dev/null +++ b/examples/objective-c/helloworld_macos/Podfile @@ -0,0 +1,9 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :macos, '10.9' + +install! 'cocoapods', :deterministic_uuids => false + +target 'HelloWorld' do + # Depend on the generated HelloWorld library. + pod 'HelloWorld', :path => '.' +end diff --git a/examples/objective-c/helloworld_macos/README.md b/examples/objective-c/helloworld_macos/README.md new file mode 100644 index 00000000000..295701b5e61 --- /dev/null +++ b/examples/objective-c/helloworld_macos/README.md @@ -0,0 +1,6 @@ +# gRPC Objective-C Mac OS Hello World Example + +A hello world example app on Mac OS. Note that Mac OS is not a first class supported platform of gRPC +Objective-C library. This example is only for reference. + +Refer to [Hello World Example](../helloworld) for instructions on installation and running. diff --git a/examples/objective-c/helloworld_macos/main.m b/examples/objective-c/helloworld_macos/main.m new file mode 100644 index 00000000000..2a98ec4966c --- /dev/null +++ b/examples/objective-c/helloworld_macos/main.m @@ -0,0 +1,43 @@ +/* + * + * 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 + +static NSString * const kHostAddress = @"localhost:50051"; + +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); + }]; + } + + return NSApplicationMain(argc, argv); +} diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index d4b0548532b..6647201714c 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-dev' - version = '0.0.3' + # version = '1.18.0-dev' + version = '0.0.4' 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-dev' + grpc_version = '1.18.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', @@ -256,6 +256,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', @@ -347,19 +348,18 @@ Pod::Spec.new do |s| '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/method_params.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', '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/retry_throttle.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', 'src/core/ext/filters/client_channel/health/health.pb.h', - 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', 'src/core/tsi/ssl/session_cache/ssl_session.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 6a434208302..3ec0852ad31 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' @@ -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', @@ -345,19 +346,18 @@ Pod::Spec.new do |s| '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/method_params.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', '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/retry_throttle.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', 'src/core/ext/filters/client_channel/health/health.pb.h', - 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', 'src/core/tsi/ssl/session_cache/ssl_session.h', @@ -681,6 +681,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', @@ -786,18 +787,17 @@ Pod::Spec.new do |s| '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/method_params.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', '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/retry_throttle.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', 'src/core/ext/filters/client_channel/health/health.pb.c', - 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', 'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc', @@ -873,6 +873,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', @@ -964,19 +965,18 @@ Pod::Spec.new do |s| '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/method_params.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', '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/retry_throttle.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', 'src/core/ext/filters/client_channel/health/health.pb.h', - 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', 'src/core/tsi/ssl/session_cache/ssl_session.h', 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/grpc.gemspec b/grpc.gemspec index a9d3a95f2c3..b5a1ef43fd3 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 ) @@ -281,19 +282,18 @@ Gem::Specification.new do |s| 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/method_params.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 ) 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/retry_throttle.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 ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) - s.files += %w( src/core/tsi/alts_transport_security.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) s.files += %w( src/core/tsi/local_transport_security.h ) s.files += %w( src/core/tsi/ssl/session_cache/ssl_session.h ) @@ -617,6 +617,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 ) @@ -725,18 +726,17 @@ Gem::Specification.new do |s| 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/method_params.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 ) 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/retry_throttle.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 ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) - s.files += %w( src/core/tsi/alts_transport_security.cc ) s.files += %w( src/core/tsi/fake_transport_security.cc ) s.files += %w( src/core/tsi/local_transport_security.cc ) s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc ) diff --git a/grpc.gyp b/grpc.gyp index c365b7e2ad9..136867378f6 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', @@ -541,18 +542,17 @@ '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/method_params.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', '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/retry_throttle.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', 'src/core/ext/filters/client_channel/health/health.pb.c', - 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', 'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc', @@ -801,12 +801,12 @@ '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/method_params.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', '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/retry_throttle.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', @@ -819,6 +819,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', @@ -1040,12 +1041,12 @@ '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/method_params.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', '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/retry_throttle.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', @@ -1058,6 +1059,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', @@ -1250,6 +1252,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', @@ -1291,12 +1294,12 @@ '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/method_params.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', '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/retry_throttle.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 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/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. */ diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index 4502b94b175..ee833960698 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -65,13 +65,13 @@ class Channel final : public ChannelInterface, friend void experimental::ChannelResetConnectionBackoff(Channel* channel); friend std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); friend class internal::InterceptedChannel; Channel(const grpc::string& host, grpc_channel* c_channel, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); internal::Call CreateCall(const internal::RpcMethod& method, diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 43188d09e70..e8a2a70581d 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -70,8 +70,8 @@ std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index b1c80764f23..5151839412b 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -69,13 +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 { - GPR_CODEGEN_ASSERT(!status_.ok()); + 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_; } 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/include/grpcpp/impl/codegen/metadata_map.h b/include/grpcpp/impl/codegen/metadata_map.h index 0bba3ed4e36..9cec54d9f01 100644 --- a/include/grpcpp/impl/codegen/metadata_map.h +++ b/include/grpcpp/impl/codegen/metadata_map.h @@ -32,11 +32,9 @@ const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin"; class MetadataMap { public: - MetadataMap() { memset(&arr_, 0, sizeof(arr_)); } + MetadataMap() { Setup(); } - ~MetadataMap() { - g_core_codegen_interface->grpc_metadata_array_destroy(&arr_); - } + ~MetadataMap() { Destroy(); } grpc::string GetBinaryErrorDetails() { // if filled_, extract from the multimap for O(log(n)) @@ -71,11 +69,24 @@ class MetadataMap { } grpc_metadata_array* arr() { return &arr_; } + void Reset() { + filled_ = false; + map_.clear(); + Destroy(); + Setup(); + } + private: bool filled_ = false; grpc_metadata_array arr_; std::multimap map_; + void Destroy() { + g_core_codegen_interface->grpc_metadata_array_destroy(&arr_); + } + + void Setup() { memset(&arr_, 0, sizeof(arr_)); } + void FillMap() { if (filled_) return; filled_ = true; diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8dfbdec3e64..d8c9e04d778 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -46,8 +46,8 @@ std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); } // namespace experimental @@ -80,8 +80,8 @@ class ChannelCredentials : private GrpcLibraryCodegen { const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); virtual std::shared_ptr CreateChannel( @@ -91,8 +91,8 @@ class ChannelCredentials : private GrpcLibraryCodegen { // 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::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) { return nullptr; }; diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index a14a4da578d..cdcac186cb6 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -111,8 +111,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// interceptors std::shared_ptr InProcessChannelWithInterceptors( const ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); private: diff --git a/package.xml b/package.xml index 69f952c4669..a354ad5fa7d 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 @@ -191,6 +191,7 @@ + @@ -286,19 +287,18 @@ - + - @@ -622,6 +622,7 @@ + @@ -730,18 +731,17 @@ - + - diff --git a/requirements.bazel.txt b/requirements.bazel.txt index efbf5314afd..61e529a6ec8 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -9,3 +9,7 @@ futures>=2.2.0 google-auth>=1.0.0 oauth2client==4.1.0 requests>=2.14.2 +urllib3==1.22 +chardet==3.0.4 +certifi==2017.4.17 +idna==2.7 diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index a923ce8e380..59ddbd82f61 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -609,6 +609,42 @@ 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 GenerateService(Printer* out, const ServiceDescriptor* service, bool generate_client, bool generate_server, bool internal_access) { @@ -637,6 +673,7 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, } if (generate_server) { GenerateBindServiceMethod(out, service); + GenerateBindServiceWithBinderMethod(out, service); } out->Outdent(); diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index d42961fc608..be7962261bc 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -34,9 +34,9 @@ #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/method_params.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/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" @@ -63,6 +63,8 @@ #include "src/core/lib/transport/status_metadata.h" using grpc_core::internal::ClientChannelMethodParams; +using grpc_core::internal::ClientChannelMethodParamsTable; +using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; /* Client channel implementation */ @@ -83,10 +85,6 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); struct external_connectivity_watcher; -typedef grpc_core::SliceHashTable< - grpc_core::RefCountedPtr> - MethodParamsTable; - typedef struct client_channel_channel_data { grpc_core::OrphanablePtr resolver; bool started_resolving; @@ -102,7 +100,7 @@ typedef struct client_channel_channel_data { /** retry throttle data */ grpc_core::RefCountedPtr retry_throttle_data; /** maps method names to method_parameters structs */ - grpc_core::RefCountedPtr method_params_table; + 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 */ @@ -251,66 +249,6 @@ static void start_resolving_locked(channel_data* chand) { &chand->on_resolver_result_changed); } -typedef struct { - char* server_name; - grpc_core::RefCountedPtr retry_throttle_data; -} service_config_parsing_state; - -static void parse_retry_throttle_params( - const grpc_json* field, service_config_parsing_state* parsing_state) { - if (strcmp(field->key, "retryThrottling") == 0) { - if (parsing_state->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; - } - } - parsing_state->retry_throttle_data = - grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( - parsing_state->server_name, max_milli_tokens, milli_token_ratio); - } -} - // Invoked from the resolver NextLocked() callback when the resolver // is shutting down. static void on_resolver_shutdown_locked(channel_data* chand, @@ -352,37 +290,6 @@ static void on_resolver_shutdown_locked(channel_data* chand, GRPC_ERROR_UNREF(error); } -// Returns the LB policy name from the resolver result. -static grpc_core::UniquePtr -get_lb_policy_name_from_resolver_result_locked(channel_data* chand) { - // Find LB policy name in channel args. - const grpc_arg* channel_arg = - grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_POLICY_NAME); - const char* lb_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 actually specified. - 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 (grpc_lb_addresses_contains_balancer_address(*addresses)) { - if (lb_policy_name != nullptr && - gpr_stricmp(lb_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", - lb_policy_name); - } - lb_policy_name = "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"; - return grpc_core::UniquePtr(gpr_strdup(lb_policy_name)); -} - static void request_reresolution_locked(void* arg, grpc_error* error) { reresolution_request_args* args = static_cast(arg); @@ -410,13 +317,14 @@ using TraceStringVector = grpc_core::InlinedVector; // *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, + 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); @@ -473,44 +381,6 @@ static void create_new_lb_policy_locked( } } -// Returns the service config (as a JSON string) from the resolver result. -// Also updates state in chand. -static grpc_core::UniquePtr -get_service_config_from_resolver_result_locked(channel_data* chand) { - const grpc_arg* channel_arg = - grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG); - const char* service_config_json = grpc_channel_arg_get_string(channel_arg); - if (service_config_json != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json); - } - grpc_core::UniquePtr service_config = - grpc_core::ServiceConfig::Create(service_config_json); - if (service_config != nullptr) { - if (chand->enable_retries) { - channel_arg = - grpc_channel_args_find(chand->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'); - service_config_parsing_state parsing_state; - parsing_state.server_name = - uri->path[0] == '/' ? uri->path + 1 : uri->path; - service_config->ParseGlobalParams(parse_retry_throttle_params, - &parsing_state); - grpc_uri_destroy(uri); - chand->retry_throttle_data = - std::move(parsing_state.retry_throttle_data); - } - chand->method_params_table = service_config->CreateMethodConfigTable( - ClientChannelMethodParams::CreateFromJson); - } - } - return grpc_core::UniquePtr(gpr_strdup(service_config_json)); -} - static void maybe_add_trace_message_for_address_changes_locked( channel_data* chand, TraceStringVector* trace_strings) { int resolution_contains_addresses = false; @@ -597,9 +467,23 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { 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 = - get_lb_policy_name_from_resolver_result_locked(chand); + 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 @@ -614,19 +498,16 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { 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); + 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(), + create_new_lb_policy_locked(chand, lb_policy_name.get(), lb_policy_config, &connectivity_state, &connectivity_error, &trace_strings); } - // Find service config. - grpc_core::UniquePtr service_config_json = - get_service_config_from_resolver_result_locked(chand); // 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 @@ -1023,13 +904,17 @@ 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. - bool retry_dispatched : 1; 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 + // setting this field. + bool retry_dispatched : 1; }; // Pending batches stored in 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 b0040457a61..6733fdca814 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -58,6 +58,8 @@ class LoadBalancingPolicy /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_LB_ADDRESSES channel arg. grpc_channel_args* args = nullptr; + /// Load balancing config from the resolver. + grpc_json* lb_config = nullptr; }; /// State used for an LB pick. @@ -92,10 +94,11 @@ class LoadBalancingPolicy LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; - /// Updates the policy with a new set of \a args from the resolver. - /// Note that the LB policy gets the set of addresses from the + /// 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. - virtual void UpdateLocked(const grpc_channel_args& args) GRPC_ABSTRACT; + 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. 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 17e0d268757..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 @@ -123,7 +123,8 @@ class GrpcLb : public LoadBalancingPolicy { public: GrpcLb(const grpc_lb_addresses* addresses, const Args& args); - void UpdateLocked(const grpc_channel_args& args) override; + 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, @@ -748,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"); @@ -802,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. @@ -1331,13 +1323,10 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void GrpcLb::UpdateLocked(const grpc_channel_args& args) { +void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { ProcessChannelArgsLocked(args); - // If fallback is configured and the RR policy already exists, update - // it with the new fallback addresses. - if (lb_fallback_timeout_ms_ > 0 && rr_policy_ != nullptr) { - CreateOrUpdateRoundRobinPolicyLocked(); - } + // 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_) { @@ -1585,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) { @@ -1683,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 { @@ -1730,7 +1718,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, rr_policy_.get()); } - rr_policy_->UpdateLocked(*args); + rr_policy_->UpdateLocked(*args, nullptr); } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); 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 eb494486b9e..d454401a669 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,8 @@ class PickFirst : public LoadBalancingPolicy { public: explicit PickFirst(const Args& args); - void UpdateLocked(const grpc_channel_args& args) override; + 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, @@ -159,7 +160,7 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p created.", this); } - UpdateLocked(*args.args); + UpdateLocked(*args.args, args.lb_config); grpc_subchannel_index_ref(); } @@ -333,7 +334,8 @@ void PickFirst::UpdateChildRefsLocked() { child_subchannels_ = std::move(cs); } -void PickFirst::UpdateLocked(const grpc_channel_args& args) { +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) { 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 e9ed85cf665..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 @@ -57,7 +57,8 @@ class RoundRobin : public LoadBalancingPolicy { public: explicit RoundRobin(const Args& args); - void UpdateLocked(const grpc_channel_args& args) override; + 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, @@ -232,7 +233,7 @@ RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) { gpr_mu_init(&child_refs_mu_); grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "round_robin"); - UpdateLocked(*args.args); + 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()); @@ -664,7 +665,8 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, notify); } -void RoundRobin::UpdateLocked(const grpc_channel_args& args) { +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)) { 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 38f8072e8d3..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 @@ -26,30 +26,26 @@ /// 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. +/// 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. /// -/// We maintain an internal round_robin policy instance for distributing +/// We maintain an internal child policy (round_robin) instance for distributing /// requests across backends. Whenever we receive a new serverlist from -/// 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 -/// resolver. +/// the balancer, we update the child policy with the new list of +/// addresses. /// -/// 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 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. +/// Once a child policy instance is in place (and getting updated as +/// described), calls for a pick, 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 xDS policy), pick +/// requests are added to a list of pending picks to be flushed and serviced +/// when the child policy instance becomes available. /// /// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the /// high level design and details. @@ -122,7 +118,8 @@ class XdsLb : public LoadBalancingPolicy { public: XdsLb(const grpc_lb_addresses* addresses, const Args& args); - void UpdateLocked(const grpc_channel_args& args) override; + 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, @@ -141,10 +138,10 @@ class XdsLb : public LoadBalancingPolicy { 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. + /// 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 RR policy, we inject our own + /// 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. @@ -202,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); @@ -266,18 +262,18 @@ class XdsLb : public LoadBalancingPolicy { 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(const 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); + // Methods for dealing with the child policy. + void CreateOrUpdateChildPolicyLocked(); + grpc_channel_args* CreateChildPolicyArgsLocked(); + void CreateChildPolicyLocked(const 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; @@ -330,14 +326,14 @@ class XdsLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // Pending picks that are waiting on the RR policy's connectivity. + // Pending picks that are waiting on the xDS 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_; + // The policy to use for the backends. + OrphanablePtr child_policy_; + grpc_connectivity_state child_connectivity_state_; + grpc_closure on_child_connectivity_changed_; + grpc_closure on_child_request_reresolution_; }; // @@ -444,7 +440,7 @@ grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { 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. + * 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 */ @@ -671,6 +667,7 @@ 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); @@ -688,38 +685,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, - 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, @@ -833,7 +800,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( // serverlist instance will be destroyed either upon the next // update or when the XdsLb instance is destroyed. xdslb_policy->serverlist_ = serverlist; - xdslb_policy->CreateOrUpdateRoundRobinPolicyLocked(); + xdslb_policy->CreateOrUpdateChildPolicyLocked(); } } else { if (grpc_lb_xds_trace.enabled()) { @@ -866,7 +833,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( &lb_calld->lb_on_balancer_message_received_); GPR_ASSERT(GRPC_CALL_OK == call_error); } else { - lb_calld->Unref(DEBUG_LOCATION, "on_message_received+grpclb_shutdown"); + lb_calld->Unref(DEBUG_LOCATION, "on_message_received+xds_shutdown"); } } @@ -944,7 +911,7 @@ grpc_lb_addresses* ExtractBalancerAddresses( * - \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 grpclb policy. */ + * - \a args: other args inherited from the xds policy. */ grpc_channel_args* BuildBalancerChannelArgs( const grpc_lb_addresses* addresses, FakeResolverResponseGenerator* response_generator, @@ -966,10 +933,10 @@ 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. + // xds LB policy, as per the special case logic in client_channel.c. 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 + // 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 @@ -991,7 +958,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( response_generator), - // A channel arg indicating the target is a grpclb load balancer. + // 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), // A channel arg indicating this is an internal channels, aka it is @@ -1014,6 +981,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // ctor and dtor // +// TODO(vishalpowar): Use lb_config in args to configure LB policy. XdsLb::XdsLb(const grpc_lb_addresses* addresses, const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), @@ -1031,11 +999,11 @@ XdsLb::XdsLb(const grpc_lb_addresses* addresses, GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_, - &XdsLb::OnRoundRobinConnectivityChangedLocked, this, + GRPC_CLOSURE_INIT(&on_child_connectivity_changed_, + &XdsLb::OnChildPolicyConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_request_reresolution_, - &XdsLb::OnRoundRobinRequestReresolutionLocked, this, + 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. @@ -1087,7 +1055,7 @@ void XdsLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - rr_policy_.reset(); + 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 @@ -1100,7 +1068,7 @@ void XdsLb::ShutdownLocked() { gpr_mu_unlock(&lb_channel_mu_); } grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "grpclb_shutdown"); + GRPC_ERROR_REF(error), "xds_shutdown"); // Clear pending picks. PendingPick* pp; while ((pp = pending_picks_) != nullptr) { @@ -1133,13 +1101,13 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { // 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, +// 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) { @@ -1159,21 +1127,21 @@ void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) { } pp = next; } - if (rr_policy_ != nullptr) { - rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); + if (child_policy_ != nullptr) { + child_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, +// 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, @@ -1195,10 +1163,10 @@ void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, } pp = next; } - if (rr_policy_ != nullptr) { - rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); + if (child_policy_ != nullptr) { + child_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, + GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } @@ -1213,22 +1181,21 @@ void XdsLb::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(); } } bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { PendingPick* pp = PendingPickCreate(pick); bool pick_done = false; - if (rr_policy_ != nullptr) { + if (child_policy_ != nullptr) { if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] about to PICK from RR %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[xdslb %p] about to PICK from policy %p", this, + child_policy_.get()); } - pick_done = - PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error); - } else { // rr_policy_ == NULL + 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."); @@ -1236,7 +1203,7 @@ bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { } else { if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, - "[xdslb %p] No RR policy. Adding to grpclb's pending picks", + "[xdslb %p] No child policy. Adding to xds's pending picks", this); } AddPendingPick(pp); @@ -1251,8 +1218,8 @@ bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { void XdsLb::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); + // 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) { grpc_core::channelz::ChannelNode* channel_node = @@ -1319,13 +1286,15 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void XdsLb::UpdateLocked(const grpc_channel_args& args) { +// TODO(vishalpowar): Use lb_config to configure LB policy. +void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { ProcessChannelArgsLocked(args); - // If fallback is configured and the RR policy already exists, update - // it with the new fallback addresses. - if (lb_fallback_timeout_ms_ > 0 && rr_policy_ != nullptr) { - CreateOrUpdateRoundRobinPolicyLocked(); - } + // 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. + if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); // Start watching the LB channel connectivity for connection, if not // already doing so. if (!watching_lb_channel_) { @@ -1393,11 +1362,10 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { if (xdslb_policy->serverlist_ == nullptr && !xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE) { if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Falling back to use backends from resolver", + gpr_log(GPR_INFO, + "[xdslb %p] Fallback timer fired. Not using fallback backends", xdslb_policy); } - GPR_ASSERT(xdslb_policy->fallback_backend_addresses_ != nullptr); - xdslb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } @@ -1447,8 +1415,8 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, 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 - // 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. + // 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: { @@ -1507,8 +1475,8 @@ void DestroyClientStats(void* arg) { } void XdsLb::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 + /* 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))) { @@ -1534,8 +1502,8 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { } /* 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 */ + * 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); PendingPickSetMetadataAndContext(pp); @@ -1560,24 +1528,24 @@ void XdsLb::AddPendingPick(PendingPick* pp) { } // -// code for interacting with the RR policy +// code for interacting with the child policy // -// Performs a pick over \a rr_policy_. Given that a pick can return +// 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::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { +bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, + grpc_error** error) { // 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); + // Pick via the child policy. + bool pick_done = child_policy_->PickLocked(pp->pick, error); if (pick_done) { PendingPickSetMetadataAndContext(pp); if (force_async) { @@ -1588,72 +1556,67 @@ bool XdsLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, Delete(pp); } // else, the pending pick will be registered and taken care of by the - // pending pick list inside the RR policy. Eventually, + // 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::CreateRoundRobinPolicyLocked(const Args& args) { - GPR_ASSERT(rr_policy_ == nullptr); - rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( +void XdsLb::CreateChildPolicyLocked(const Args& args) { + GPR_ASSERT(child_policy_ == nullptr); + child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( "round_robin", args); - if (GPR_UNLIKELY(rr_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a RoundRobin policy", this); + if (GPR_UNLIKELY(child_policy_ == nullptr)) { + 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_rr_reresolution_requested"); + auto self = Ref(DEBUG_LOCATION, "on_child_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(), + 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 RR. + // 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_rr_connectivity_changed"); + self = Ref(DEBUG_LOCATION, "on_child_connectivity_changed"); self.release(); - rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_, - &on_rr_connectivity_changed_); - rr_policy_->ExitIdleLocked(); - // Send pending picks to RR policy. + 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 RR %p", this, - rr_policy_.get()); + 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; - PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error); + PickFromChildPolicyLocked(true /* force_async */, pp, &error); } } -grpc_channel_args* XdsLb::CreateRoundRobinPolicyArgsLocked() { +grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { 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 { - // 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 - // picks pending. - GPR_ASSERT(fallback_backend_addresses_ != nullptr); - addresses = grpc_lb_addresses_copy(fallback_backend_addresses_); - } + // 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; GPR_ASSERT(addresses != nullptr); // Replace the LB addresses in the channel args that we pass down to // the subchannel. @@ -1673,66 +1636,68 @@ grpc_channel_args* XdsLb::CreateRoundRobinPolicyArgsLocked() { return args; } -void XdsLb::CreateOrUpdateRoundRobinPolicyLocked() { +void XdsLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; - grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked(); + grpc_channel_args* args = CreateChildPolicyArgsLocked(); GPR_ASSERT(args != nullptr); - if (rr_policy_ != nullptr) { + if (child_policy_ != nullptr) { if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Updating RR policy %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[xdslb %p] Updating the child policy %p", this, + child_policy_.get()); } - rr_policy_->UpdateLocked(*args); + // TODO(vishalpowar): Pass the correct LB config. + child_policy_->UpdateLocked(*args, nullptr); } 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; - CreateRoundRobinPolicyLocked(lb_policy_args); + CreateChildPolicyLocked(lb_policy_args); if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Created new RR policy %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, + child_policy_.get()); } } grpc_channel_args_destroy(args); } -void XdsLb::OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error) { +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_rr_reresolution_requested"); + 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 the internal RR policy (%p).", - xdslb_policy, xdslb_policy->rr_policy_.get()); + 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 RR - // policy. Otherwise, handle the re-resolution request using the - // grpclb policy's original re-resolution closure. + // 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 RR policy. - xdslb_policy->rr_policy_->SetReresolutionClosureLocked( - &xdslb_policy->on_rr_request_reresolution_); + // Give back the wrapper closure to the child policy. + xdslb_policy->child_policy_->SetReresolutionClosureLocked( + &xdslb_policy->on_child_request_reresolution_); } -void XdsLb::UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error) { +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 RR policy. + * input coming from the status of the child policy. * - * current state (grpclb's) + * current state (xds's) * | - * v || I | C | R | TF | SD | <- new state (RR's) + * v || I | C | R | TF | SD | <- new state (child policy's) * ===++====+=====+=====+======+======+ * I || I | C | R | [I] | [I] | * ---++----+-----+-----+------+------+ @@ -1745,52 +1710,51 @@ void XdsLb::UpdateConnectivityStateFromRoundRobinPolicyLocked( * 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. + * 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 RR instance. + * 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 (rr_connectivity_state_) { + switch (child_connectivity_state_) { case GRPC_CHANNEL_TRANSIENT_FAILURE: case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE); + GPR_ASSERT(child_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); + GPR_ASSERT(child_state_error == GRPC_ERROR_NONE); } if (grpc_lb_xds_trace.enabled()) { - gpr_log( - GPR_INFO, - "[xdslb %p] Setting grpclb's state to %s from new RR policy %p state.", - this, grpc_connectivity_state_name(rr_connectivity_state_), - rr_policy_.get()); + 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_, rr_connectivity_state_, - rr_state_error, + grpc_connectivity_state_set(&state_tracker_, child_connectivity_state_, + child_state_error, "update_lb_connectivity_status_locked"); } -void XdsLb::OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error) { +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_rr_connectivity_changed"); + xdslb_policy->Unref(DEBUG_LOCATION, "on_child_connectivity_changed"); return; } - xdslb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked( + xdslb_policy->UpdateConnectivityStateFromChildPolicyLocked( GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_rr_connectivity_changed" ref. - xdslb_policy->rr_policy_->NotifyOnStateChangeLocked( - &xdslb_policy->rr_connectivity_state_, - &xdslb_policy->on_rr_connectivity_changed_); + // Resubscribe. Reuse the "on_child_connectivity_changed" ref. + xdslb_policy->child_policy_->NotifyOnStateChangeLocked( + &xdslb_policy->child_connectivity_state_, + &xdslb_policy->on_child_connectivity_changed_); } // 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 d651b1120d3..ad459c9c8cf 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -94,4 +94,9 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( return factory->CreateLoadBalancingPolicy(args); } +bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { + GPR_ASSERT(g_state != nullptr); + return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; +} + } // 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 2e9bb061ed6..338f7c9f696 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -47,6 +47,10 @@ class LoadBalancingPolicyRegistry { /// Creates an LB policy of the type specified by \a name. static OrphanablePtr CreateLoadBalancingPolicy( const char* name, const LoadBalancingPolicy::Args& args); + + /// Returns true if the LB policy factory specified by \a name exists in this + /// registry. + static bool LoadBalancingPolicyExists(const char* name); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/method_params.cc b/src/core/ext/filters/client_channel/method_params.cc deleted file mode 100644 index 1f116bb67d1..00000000000 --- a/src/core/ext/filters/client_channel/method_params.cc +++ /dev/null @@ -1,178 +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 -#include - -#include "src/core/ext/filters/client_channel/method_params.h" -#include "src/core/lib/channel/status_util.h" -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/memory.h" - -// As per the retry design, we do not allow more than 5 retry attempts. -#define MAX_MAX_RETRY_ATTEMPTS 5 - -namespace grpc_core { -namespace internal { - -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 -bool ParseDuration(grpc_json* field, grpc_millis* duration) { - if (field->type != GRPC_JSON_STRING) return false; - size_t len = strlen(field->value); - if (field->value[len - 1] != 's') return false; - UniquePtr buf(gpr_strdup(field->value)); - *(buf.get() + len - 1) = '\0'; // Remove trailing 's'. - char* decimal_point = strchr(buf.get(), '.'); - int nanos = 0; - if (decimal_point != nullptr) { - *decimal_point = '\0'; - nanos = gpr_parse_nonnegative_int(decimal_point + 1); - if (nanos == -1) { - return false; - } - int num_digits = static_cast(strlen(decimal_point + 1)); - if (num_digits > 9) { // We don't accept greater precision than nanos. - return false; - } - for (int i = 0; i < (9 - num_digits); ++i) { - nanos *= 10; - } - } - int seconds = - decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get()); - if (seconds == -1) return false; - *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS; - return true; -} - -UniquePtr ParseRetryPolicy( - grpc_json* field) { - auto retry_policy = MakeUnique(); - if (field->type != GRPC_JSON_OBJECT) return nullptr; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return nullptr; - 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; - retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value); - if (retry_policy->max_attempts <= 1) return nullptr; - if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) { - gpr_log(GPR_ERROR, - "service config: clamped retryPolicy.maxAttempts at %d", - MAX_MAX_RETRY_ATTEMPTS); - 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 (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { - return nullptr; - } - 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) 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 (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) != - 1) { - return nullptr; - } - 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. - } - 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; - grpc_status_code status; - if (!grpc_status_code_from_string(element->value, &status)) { - return nullptr; - } - retry_policy->retryable_status_codes.Add(status); - } - if (retry_policy->retryable_status_codes.Empty()) return nullptr; - } - } - // 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; - } - return retry_policy; -} - -} // namespace - -RefCountedPtr -ClientChannelMethodParams::CreateFromJson(const grpc_json* json) { - RefCountedPtr method_params = - MakeRefCounted(); - 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 (!ParseWaitForReady(field, &method_params->wait_for_ready_)) { - return nullptr; - } - } 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. - } - method_params->retry_policy_ = ParseRetryPolicy(field); - if (method_params->retry_policy_ == nullptr) return nullptr; - } - } - return method_params; -} - -} // namespace internal -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/method_params.h b/src/core/ext/filters/client_channel/method_params.h deleted file mode 100644 index a31d360f172..00000000000 --- a/src/core/ext/filters/client_channel/method_params.h +++ /dev/null @@ -1,78 +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 GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H - -#include - -#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" - -namespace grpc_core { -namespace internal { - -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 -} // namespace grpc_core - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_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 01796ca08f4..90bc88961d9 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 @@ -120,6 +120,8 @@ class AresDnsResolver : public Resolver { grpc_lb_addresses* lb_addresses_ = nullptr; /// currently resolving service config char* service_config_json_ = nullptr; + // has shutdown been initiated + bool shutdown_initiated_ = false; }; AresDnsResolver::AresDnsResolver(const ResolverArgs& args) @@ -197,6 +199,7 @@ void AresDnsResolver::ResetBackoffLocked() { } void AresDnsResolver::ShutdownLocked() { + shutdown_initiated_ = true; if (have_next_resolution_timer_) { grpc_timer_cancel(&next_resolution_timer_); } @@ -213,9 +216,13 @@ 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_); r->have_next_resolution_timer_ = false; - if (error == GRPC_ERROR_NONE) { + if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) { if (!r->resolving_) { + GRPC_CARES_TRACE_LOG("%p start resolving due to re-resolution timer", r); r->StartResolvingLocked(); } } @@ -301,13 +308,12 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { gpr_free(r->pending_request_); r->pending_request_ = nullptr; if (r->lb_addresses_ != nullptr) { - static const char* args_to_remove[2]; + static const char* args_to_remove[1]; size_t num_args_to_remove = 0; - grpc_arg new_args[3]; + grpc_arg args_to_add[2]; size_t num_args_to_add = 0; - new_args[num_args_to_add++] = + args_to_add[num_args_to_add++] = grpc_lb_addresses_create_channel_arg(r->lb_addresses_); - grpc_core::UniquePtr service_config; char* service_config_string = nullptr; if (r->service_config_json_ != nullptr) { service_config_string = ChooseServiceConfig(r->service_config_json_); @@ -316,31 +322,19 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { gpr_log(GPR_INFO, "selected service config choice: %s", service_config_string); args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG; - new_args[num_args_to_add++] = grpc_channel_arg_string_create( + args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( (char*)GRPC_ARG_SERVICE_CONFIG, service_config_string); - service_config = - grpc_core::ServiceConfig::Create(service_config_string); - if (service_config != nullptr) { - const char* lb_policy_name = - service_config->GetLoadBalancingPolicyName(); - if (lb_policy_name != nullptr) { - args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME; - new_args[num_args_to_add++] = grpc_channel_arg_string_create( - (char*)GRPC_ARG_LB_POLICY_NAME, - const_cast(lb_policy_name)); - } - } } } result = grpc_channel_args_copy_and_add_and_remove( - r->channel_args_, args_to_remove, num_args_to_remove, new_args, + 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_); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); - } else { + } else if (!r->shutdown_initiated_) { const char* msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); grpc_millis next_try = r->backoff_.NextAttemptTime(); 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 144ac24a56a..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 @@ -103,7 +103,7 @@ void FakeResolver::NextLocked(grpc_channel_args** target_result, } void FakeResolver::RequestReresolutionLocked() { - if (reresolution_results_ != nullptr) { + if (reresolution_results_ != nullptr || return_failure_) { grpc_channel_args_destroy(next_results_); next_results_ = grpc_channel_args_copy(reresolution_results_); MaybeFinishNextLocked(); @@ -141,6 +141,7 @@ struct SetResponseClosureArg { grpc_closure set_response_closure; FakeResolverResponseGenerator* generator; grpc_channel_args* response; + bool immediate = true; }; void FakeResolverResponseGenerator::SetResponseLocked(void* arg, @@ -194,7 +195,7 @@ void FakeResolverResponseGenerator::SetFailureLocked(void* arg, SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; resolver->return_failure_ = true; - resolver->MaybeFinishNextLocked(); + if (closure_arg->immediate) resolver->MaybeFinishNextLocked(); Delete(closure_arg); } @@ -209,6 +210,18 @@ void FakeResolverResponseGenerator::SetFailure() { GRPC_ERROR_NONE); } +void FakeResolverResponseGenerator::SetFailureOnReresolution() { + GPR_ASSERT(resolver_ != nullptr); + SetResponseClosureArg* closure_arg = New(); + closure_arg->generator = this; + closure_arg->immediate = false; + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetFailureLocked, + closure_arg, + grpc_combiner_scheduler(resolver_->combiner())), + GRPC_ERROR_NONE); +} + namespace { static void* response_generator_arg_copy(void* p) { 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 74a3062e7f4..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 @@ -61,6 +61,10 @@ class FakeResolverResponseGenerator // returning a null result with no error). void SetFailure(); + // Same as SetFailure(), but instead of returning the error + // immediately, waits for the next call to RequestReresolutionLocked(). + void SetFailureOnReresolution(); + // Returns a channel arg containing \a generator. static grpc_arg MakeChannelArg(FakeResolverResponseGenerator* generator); diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc new file mode 100644 index 00000000000..82a26ace634 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -0,0 +1,384 @@ +/* + * + * 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/resolver_result_parsing.h" + +#include +#include +#include + +#include +#include +#include + +#include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" + +// As per the retry design, we do not allow more than 5 retry attempts. +#define MAX_MAX_RETRY_ATTEMPTS 5 + +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); +} + +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); + } + } +} + +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(); + } + // 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); + lb_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. + 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 && + gpr_stricmp(lb_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", + lb_policy_name); + } + lb_policy_name = "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)); +} + +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. + // 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. + } + // 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; + } + grpc_core::UniquePtr lb_policy_name = + ConvertCamelToSnake(policy_content->key); + if (!grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + lb_policy_name.get())) { + continue; + } + lb_policy_name_ = std::move(lb_policy_name); + lb_policy_config_ = policy_content->child; + return; + } +} + +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 +bool ParseDuration(grpc_json* field, grpc_millis* duration) { + if (field->type != GRPC_JSON_STRING) return false; + size_t len = strlen(field->value); + if (field->value[len - 1] != 's') return false; + UniquePtr buf(gpr_strdup(field->value)); + *(buf.get() + len - 1) = '\0'; // Remove trailing 's'. + char* decimal_point = strchr(buf.get(), '.'); + int nanos = 0; + if (decimal_point != nullptr) { + *decimal_point = '\0'; + nanos = gpr_parse_nonnegative_int(decimal_point + 1); + if (nanos == -1) { + return false; + } + int num_digits = static_cast(strlen(decimal_point + 1)); + if (num_digits > 9) { // We don't accept greater precision than nanos. + return false; + } + for (int i = 0; i < (9 - num_digits); ++i) { + nanos *= 10; + } + } + int seconds = + decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get()); + if (seconds == -1) return false; + *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS; + return true; +} + +UniquePtr ParseRetryPolicy( + grpc_json* field) { + auto retry_policy = MakeUnique(); + if (field->type != GRPC_JSON_OBJECT) return nullptr; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) return nullptr; + 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; + retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value); + if (retry_policy->max_attempts <= 1) return nullptr; + if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) { + gpr_log(GPR_ERROR, + "service config: clamped retryPolicy.maxAttempts at %d", + MAX_MAX_RETRY_ATTEMPTS); + 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 (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { + return nullptr; + } + 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) 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 (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) != + 1) { + return nullptr; + } + 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. + } + 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; + grpc_status_code status; + if (!grpc_status_code_from_string(element->value, &status)) { + return nullptr; + } + retry_policy->retryable_status_codes.Add(status); + } + if (retry_policy->retryable_status_codes.Empty()) return nullptr; + } + } + // 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; + } + return retry_policy; +} + +} // namespace + +RefCountedPtr +ClientChannelMethodParams::CreateFromJson(const grpc_json* json) { + RefCountedPtr method_params = + MakeRefCounted(); + 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 (!ParseWaitForReady(field, &method_params->wait_for_ready_)) { + return nullptr; + } + } 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. + } + method_params->retry_policy_ = ParseRetryPolicy(field); + if (method_params->retry_policy_ == nullptr) return nullptr; + } + } + return method_params; +} + +} // namespace internal +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h new file mode 100644 index 00000000000..f1fb7406bcb --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -0,0 +1,146 @@ +/* + * + * 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_RESOLVER_RESULT_PARSING_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H + +#include + +#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" +#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 { + +class ClientChannelMethodParams; + +// A table mapping from a method name to its method parameters. +typedef grpc_core::SliceHashTable< + grpc_core::RefCountedPtr> + ClientChannelMethodParamsTable; + +// 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 + // for later consumption. Tries to parse retry parameters only if parse_retry + // is true. + ProcessedResolverResult(const grpc_channel_args* resolver_result, + bool parse_retry); + + // Getters. Any managed object's ownership is transferred. + grpc_core::UniquePtr service_config_json() { + return std::move(service_config_json_); + } + grpc_core::RefCountedPtr retry_throttle_data() { + return std::move(retry_throttle_data_); + } + grpc_core::RefCountedPtr + method_params_table() { + return std::move(method_params_table_); + } + grpc_core::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, + bool parse_retry); + + // Finds the LB policy name (when no LB config was found). + void ProcessLbPolicyName(const grpc_channel_args* resolver_result); + + // Parses the service config. Intended to be used by + // ServiceConfig::ParseGlobalParams. + static void ParseServiceConfig(const grpc_json* field, + ProcessedResolverResult* parsing_state); + // Parses the LB config from service config. + void ParseLbConfigFromServiceConfig(const grpc_json* field); + // Parses the retry throttle parameters from service config. + void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field); + + // Service config. + grpc_core::UniquePtr service_config_json_; + grpc_core::UniquePtr service_config_; + // LB policy. + grpc_json* lb_policy_config_ = nullptr; + grpc_core::UniquePtr lb_policy_name_; + // Retry throttle data. + char* server_name_ = nullptr; + grpc_core::RefCountedPtr retry_throttle_data_; + // Method params table. + grpc_core::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 +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 978ecd59e4c..99c675f503a 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. @@ -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" @@ -154,6 +155,7 @@ bool g_flow_control_enabled = true; /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ + grpc_chttp2_transport::~grpc_chttp2_transport() { size_t i; @@ -168,6 +170,9 @@ 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); @@ -206,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); @@ -495,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 @@ -1065,11 +1059,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); + cl); } /* Callback from the grpc_endpoint after bytes have been written by calling @@ -1393,6 +1389,8 @@ 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, @@ -2837,8 +2835,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; } @@ -2863,14 +2861,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); @@ -3190,8 +3180,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/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc new file mode 100644 index 00000000000..f30d41c3326 --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -0,0 +1,51 @@ +/* + * + * 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 (*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* 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); + } + } + 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*)) { + 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 new file mode 100644 index 00000000000..d8701077494 --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -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. + * + */ + +#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H +#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H + +#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 { + 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; + } + + /* Executes a function \a fn with each context in the list and \a ts. It also + * frees up the entire list after this operation. */ + static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); + + private: + grpc_chttp2_stream* s_ = nullptr; + ContextList* next_ = nullptr; + size_t byte_offset_ = 0; +}; + +void grpc_http2_set_write_timestamps_callback( + void (*fn)(void*, grpc_core::Timestamps*)); +} /* namespace grpc_core */ + +#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_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 3ee408c103e..6aa68f5d4a9 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -45,6 +45,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 { @@ -232,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); @@ -252,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 == @@ -286,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; @@ -481,7 +489,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 = nullptr; grpc_core::RefCountedPtr channelz_socket; uint32_t num_messages_in_next_write = 0; }; @@ -498,6 +506,7 @@ struct grpc_chttp2_stream { const void* server_data, gpr_arena* arena); ~grpc_chttp2_stream(); + void* context; grpc_chttp2_transport* t; grpc_stream_refcount* refcount; @@ -633,8 +642,12 @@ struct grpc_chttp2_stream { /** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed */ bool unprocessed_incoming_frames_decompressed = false; + /** 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; + /** Byte counter for number of bytes written */ + size_t byte_counter = 0; }; /** Transport writing call flow: @@ -786,8 +799,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); diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index d533989444c..265d3365d3c 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 @@ -362,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; } @@ -496,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/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,13 +128,25 @@ class InlinedVector { size_--; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + size_t capacity() const { return capacity_; } + + void clear() { + destroy_elements(); + init_data(); + } + + private: void copy_from(const InlinedVector& v) { - // if v is allocated, copy over the buffer. + // if v is allocated, make sure we have enough capacity. 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 elements + for (size_t i = 0; i < v.size_; ++i) { + new (&(data()[i])) T(v[i]); } // copy over metadata size_ = v.size_; @@ -145,11 +154,12 @@ class InlinedVector { } void move_from(InlinedVector& v) { - // if v is allocated, then we steal its buffer, else we copy it. + // if v is allocated, then we steal its dynamic array; otherwise, we + // move the elements individually. if (v.dynamic_ != nullptr) { dynamic_ = v.dynamic_; } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); + move_elements(v.data(), data(), v.size_); } // copy over metadata size_ = v.size_; @@ -158,17 +168,13 @@ class InlinedVector { v.init_data(); } - size_t size() const { return size_; } - bool empty() const { return size_ == 0; } - - size_t capacity() const { return capacity_; } - - void clear() { - destroy_elements(); - 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(); + } } - private: void init_data() { dynamic_ = nullptr; size_ = 0; 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 diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 03c293f6ed9..98de1a3653f 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -21,9 +21,12 @@ #include +#include #include #include +#include +#include #include #include "src/core/lib/debug/trace.h" @@ -34,14 +37,103 @@ namespace grpc_core { +// PolymorphicRefCount enforces polymorphic destruction of RefCounted. +class PolymorphicRefCount { + public: + GRPC_ABSTRACT_BASE_CLASS + + protected: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + virtual ~PolymorphicRefCount() = default; +}; + +// NonPolymorphicRefCount does not enforce polymorphic destruction of +// RefCounted. Please refer to grpc_core::RefCounted for more details, and +// when in doubt use PolymorphicRefCount. +class NonPolymorphicRefCount { + public: + GRPC_ABSTRACT_BASE_CLASS + + protected: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + ~NonPolymorphicRefCount() = default; +}; + +// RefCount is a simple atomic ref-count. +// +// This is a C++ implementation of gpr_refcount, with inline functions. Due to +// inline functions, this class is significantly more efficient than +// gpr_refcount and should be preferred over gpr_refcount whenever possible. +// +// TODO(soheil): Remove gpr_refcount after submitting the GRFC and the paragraph +// above. +class RefCount { + public: + using Value = intptr_t; + + // `init` is the initial refcount stored in this object. + constexpr explicit RefCount(Value init = 1) : 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)); + } + + // 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)); + assert(prior > 0); +#else + Ref(); +#endif + } + + // 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)); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + Value get() const { return value_.load(std::memory_order_relaxed); } + + private: + std::atomic value_; +}; + // A base class for reference-counted objects. // New objects should be created via New() and start with a refcount of 1. // When the refcount reaches 0, the object will be deleted via Delete(). // // This will commonly be used by CRTP (curiously-recurring template pattern) // e.g., class MyClass : public RefCounted -template -class RefCounted { +// +// Use PolymorphicRefCount and NonPolymorphicRefCount to select between +// different implementations of RefCounted. +// +// Note that NonPolymorphicRefCount does not support polymorphic destruction. +// So, use NonPolymorphicRefCount only when both of the following conditions +// are guaranteed to hold: +// (a) Child is a concrete leaf class in RefCounted, and +// (b) you are gauranteed to call Unref only on concrete leaf classes and not +// their parents. +// +// The following example is illegal, because calling Unref() will not call +// the dtor of Child. +// +// class Parent : public RefCounted {} +// class Child : public Parent {} +// +// Child* ch; +// ch->Unref(); +// +template +class RefCounted : public Impl { public: RefCountedPtr Ref() GRPC_MUST_USE_RESULT { IncrementRefCount(); @@ -53,7 +145,7 @@ class RefCounted { // private, since it will only be used by RefCountedPtr<>, which is a // friend of this class. void Unref() { - if (gpr_unref(&refs_)) { + if (refs_.Unref()) { Delete(static_cast(this)); } } @@ -67,18 +159,19 @@ class RefCounted { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - RefCounted() { gpr_ref_init(&refs_, 1); } + RefCounted() = default; - virtual ~RefCounted() {} + // Note: Depending on the Impl used, this dtor can be implicitly virtual. + ~RefCounted() = default; private: // Allow RefCountedPtr<> to access IncrementRefCount(). template friend class RefCountedPtr; - void IncrementRefCount() { gpr_ref(&refs_); } + void IncrementRefCount() { refs_.Ref(); } - gpr_refcount refs_; + RefCount refs_; }; // An alternative version of the RefCounted base class that @@ -87,8 +180,8 @@ class RefCounted { // 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 { +template +class RefCountedWithTracing : public Impl { public: RefCountedPtr Ref() GRPC_MUST_USE_RESULT { IncrementRefCount(); @@ -98,7 +191,7 @@ class RefCountedWithTracing { 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 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); @@ -112,14 +205,14 @@ class RefCountedWithTracing { // 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 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); @@ -140,26 +233,25 @@ class RefCountedWithTracing { : RefCountedWithTracing(static_cast(nullptr)) {} explicit RefCountedWithTracing(TraceFlag* trace_flag) - : trace_flag_(trace_flag) { - gpr_ref_init(&refs_, 1); - } + : trace_flag_(trace_flag) {} #ifdef NDEBUG explicit RefCountedWithTracing(DebugOnlyTraceFlag* trace_flag) : RefCountedWithTracing() {} #endif - virtual ~RefCountedWithTracing() {} + // 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() { gpr_ref(&refs_); } + void IncrementRefCount() { refs_.Ref(); } TraceFlag* trace_flag_ = nullptr; - gpr_refcount refs_; + RefCount refs_; }; } // namespace grpc_core diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h index c2dfbdd90f0..facd7c6dce6 100644 --- a/src/core/lib/gprpp/ref_counted_ptr.h +++ b/src/core/lib/gprpp/ref_counted_ptr.h @@ -21,6 +21,7 @@ #include +#include #include #include "src/core/lib/gprpp/memory.h" @@ -74,6 +75,8 @@ class RefCountedPtr { } template RefCountedPtr(const RefCountedPtr& other) { + static_assert(std::has_virtual_destructor::value, + "T does not have a virtual dtor"); if (other.value_ != nullptr) other.value_->IncrementRefCount(); value_ = other.value_; } @@ -89,6 +92,8 @@ class RefCountedPtr { } template RefCountedPtr& operator=(const RefCountedPtr& other) { + static_assert(std::has_virtual_destructor::value, + "T does not have a virtual dtor"); // 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(); @@ -102,8 +107,14 @@ class RefCountedPtr { } // If value is non-null, we take ownership of a ref to it. + void reset(T* value) { + if (value_ != nullptr) value_->Unref(); + value_ = value; + } template void reset(Y* value) { + static_assert(std::has_virtual_destructor::value, + "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(); value_ = value; } diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 6ada23db1c2..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; @@ -55,10 +58,16 @@ 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, @@ -99,18 +108,20 @@ 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; while (elem != nullptr) { - if (timestamps_callback) { - timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); - } + timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); 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..627f1bde99a 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 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 @@ -67,13 +69,13 @@ 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: 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 */ @@ -82,7 +84,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/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 44fb47e19d9..06316c60315 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -61,3 +61,7 @@ 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) { + return ep->vtable->can_track_err(ep); +} 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_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/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/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..32d1b6c43ef 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,19 +237,22 @@ 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 */ +} + +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); - 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) { @@ -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/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"); } 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 46afda17742..eb29973514f 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -33,8 +33,10 @@ #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/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" @@ -57,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(); } @@ -154,6 +157,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/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); 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 diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 8553ed0db4e..0bff74e88b3 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -76,6 +76,8 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd, if (!grpc_is_unix_socket(addr)) { err = grpc_set_socket_low_latency(fd, 1); if (err != GRPC_ERROR_NONE) goto error; + err = grpc_set_socket_reuse_addr(fd, 1); + if (err != GRPC_ERROR_NONE) goto error; err = grpc_set_socket_tcp_user_timeout(fd, channel_args, true /* is_client */); if (err != GRPC_ERROR_NONE) goto error; 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 aa2704ce263..cfcb190d601 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); } @@ -384,6 +391,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); } @@ -621,7 +634,7 @@ 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->tb_head, static_cast(tcp->bytes_counter + length), tcp->outgoing_buffer_arg); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; @@ -673,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; @@ -706,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) { @@ -719,8 +730,9 @@ 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; } + bool seen = false; for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET || @@ -732,9 +744,13 @@ 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; } - process_timestamp(tcp, &msg, cmsg); + cmsg = process_timestamp(tcp, &msg, cmsg); + seen = true; + } + if (!seen) { + return; } } } @@ -749,20 +765,17 @@ 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)); TCP_UNREF(tcp, "error-tracking"); return; } /* 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); @@ -784,6 +797,19 @@ 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); + 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 @@ -831,8 +857,10 @@ 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)) { + tcp_shutdown_buffer_list(tcp); return true; /* something went wrong with timestamps */ + } } else { msg.msg_control = nullptr; msg.msg_controllen = 0; @@ -856,10 +884,12 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { } else if (errno == EPIPE) { *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 { *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; } } @@ -936,17 +966,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()); } @@ -999,6 +1030,22 @@ 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) { + 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, @@ -1008,7 +1055,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 @@ -1069,6 +1117,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); @@ -1113,6 +1162,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); } 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, diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index 34d8435907f..14fb55884f1 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -416,6 +416,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, @@ -425,7 +430,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/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 735a78ad086..89b3f77822c 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -694,6 +694,10 @@ static void cancel_with_error(grpc_call* c, grpc_error* error) { execute_batch(c, op, &state->start_batch); } +void grpc_call_cancel_internal(grpc_call* call) { + cancel_with_error(call, GRPC_ERROR_CANCELLED); +} + static grpc_error* error_from_status(grpc_status_code status, const char* description) { // copying 'description' is needed to ensure the grpc_call_cancel_with_status diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index b34260505ae..bd7295fe110 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -81,6 +81,10 @@ grpc_call_error grpc_call_start_batch_and_execute(grpc_call* call, size_t nops, grpc_closure* closure); +/* gRPC core internal version of grpc_call_cancel that does not create + * exec_ctx. */ +void grpc_call_cancel_internal(grpc_call* call); + /* Given the top call_element, get the call object. */ grpc_call* grpc_call_from_top_element(grpc_call_element* surface_element); 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 diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 93b19338098..5dc81b29bb7 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -47,6 +47,10 @@ grpc_core::TraceFlag grpc_server_channel_trace(false, "server_channel"); +static void server_on_recv_initial_metadata(void* ptr, grpc_error* error); +static void server_recv_trailing_metadata_ready(void* user_data, + grpc_error* error); + namespace { struct listener { void* arg; @@ -128,38 +132,62 @@ typedef enum { typedef struct request_matcher request_matcher; struct call_data { + call_data(grpc_call_element* elem, const grpc_call_element_args& args) + : call(grpc_call_from_top_element(elem)), + call_combiner(args.call_combiner) { + GRPC_CLOSURE_INIT(&server_on_recv_initial_metadata, + ::server_on_recv_initial_metadata, elem, + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready, + server_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); + } + ~call_data() { + GPR_ASSERT(state != PENDING); + GRPC_ERROR_UNREF(recv_initial_metadata_error); + if (host_set) { + grpc_slice_unref_internal(host); + } + if (path_set) { + grpc_slice_unref_internal(path); + } + grpc_metadata_array_destroy(&initial_metadata); + grpc_byte_buffer_destroy(payload); + } + grpc_call* call; - gpr_atm state; + gpr_atm state = NOT_STARTED; - bool path_set; - bool host_set; + bool path_set = false; + bool host_set = false; grpc_slice path; grpc_slice host; - grpc_millis deadline; + grpc_millis deadline = GRPC_MILLIS_INF_FUTURE; - grpc_completion_queue* cq_new; + grpc_completion_queue* cq_new = nullptr; - grpc_metadata_batch* recv_initial_metadata; - uint32_t recv_initial_metadata_flags; - grpc_metadata_array initial_metadata; + grpc_metadata_batch* recv_initial_metadata = nullptr; + uint32_t recv_initial_metadata_flags = 0; + grpc_metadata_array initial_metadata = + grpc_metadata_array(); // Zero-initialize the C struct. - request_matcher* matcher; - grpc_byte_buffer* payload; + request_matcher* matcher = nullptr; + grpc_byte_buffer* payload = nullptr; grpc_closure got_initial_metadata; grpc_closure server_on_recv_initial_metadata; grpc_closure kill_zombie_closure; grpc_closure* on_done_recv_initial_metadata; grpc_closure recv_trailing_metadata_ready; - grpc_error* recv_initial_metadata_error; + grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; grpc_closure* original_recv_trailing_metadata_ready; - grpc_error* recv_trailing_metadata_error; - bool seen_recv_trailing_metadata_ready; + grpc_error* recv_trailing_metadata_error = GRPC_ERROR_NONE; + bool seen_recv_trailing_metadata_ready = false; grpc_closure publish; - call_data* pending_next; + call_data* pending_next = nullptr; grpc_call_combiner* call_combiner; }; @@ -875,40 +903,18 @@ static void channel_connectivity_changed(void* cd, grpc_error* error) { static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { - call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - memset(calld, 0, sizeof(call_data)); - calld->deadline = GRPC_MILLIS_INF_FUTURE; - calld->call = grpc_call_from_top_element(elem); - calld->call_combiner = args->call_combiner; - - GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata, - server_on_recv_initial_metadata, elem, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - server_recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); server_ref(chand->server); + new (elem->call_data) call_data(elem, *args); return GRPC_ERROR_NONE; } static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { - channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - - GPR_ASSERT(calld->state != PENDING); - GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); - if (calld->host_set) { - grpc_slice_unref_internal(calld->host); - } - if (calld->path_set) { - grpc_slice_unref_internal(calld->path); - } - grpc_metadata_array_destroy(&calld->initial_metadata); - grpc_byte_buffer_destroy(calld->payload); - + calld->~call_data(); + channel_data* chand = static_cast(elem->channel_data); server_unref(chand->server); } 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/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/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index cbdb77c8441..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" @@ -149,7 +150,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) { 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 */ diff --git a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc index c0c17b0a4bd..92085d31d70 100644 --- a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc @@ -28,8 +28,6 @@ void grpc_deadline_filter_init(void); void grpc_deadline_filter_shutdown(void); void grpc_client_channel_init(void); void grpc_client_channel_shutdown(void); -void grpc_tsi_alts_init(void); -void grpc_tsi_alts_shutdown(void); void grpc_register_built_in_plugins(void) { grpc_register_plugin(grpc_http_filters_init, @@ -40,6 +38,4 @@ void grpc_register_built_in_plugins(void) { grpc_deadline_filter_shutdown); grpc_register_plugin(grpc_client_channel_init, grpc_client_channel_shutdown); - grpc_register_plugin(grpc_tsi_alts_init, - grpc_tsi_alts_shutdown); } diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc index 94c2493d5e5..cde40ef65cf 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_plugin_registry.cc @@ -28,8 +28,6 @@ void grpc_deadline_filter_init(void); void grpc_deadline_filter_shutdown(void); void grpc_client_channel_init(void); void grpc_client_channel_shutdown(void); -void grpc_tsi_alts_init(void); -void grpc_tsi_alts_shutdown(void); void grpc_inproc_plugin_init(void); void grpc_inproc_plugin_shutdown(void); void grpc_resolver_fake_init(void); @@ -66,8 +64,6 @@ void grpc_register_built_in_plugins(void) { grpc_deadline_filter_shutdown); grpc_register_plugin(grpc_client_channel_init, grpc_client_channel_shutdown); - grpc_register_plugin(grpc_tsi_alts_init, - grpc_tsi_alts_shutdown); grpc_register_plugin(grpc_inproc_plugin_init, grpc_inproc_plugin_shutdown); grpc_register_plugin(grpc_resolver_fake_init, diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc index 941ca131143..1de6264183a 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc @@ -376,7 +376,7 @@ static void handshaker_client_shutdown(alts_handshaker_client* c) { alts_grpc_handshaker_client* client = reinterpret_cast(c); if (client->call != nullptr) { - GPR_ASSERT(grpc_call_cancel(client->call, nullptr) == GRPC_CALL_OK); + grpc_call_cancel_internal(client->call); } } diff --git a/src/core/tsi/alts/handshaker/alts_shared_resource.cc b/src/core/tsi/alts/handshaker/alts_shared_resource.cc index ffb5e1c6550..3501257f052 100644 --- a/src/core/tsi/alts/handshaker/alts_shared_resource.cc +++ b/src/core/tsi/alts/handshaker/alts_shared_resource.cc @@ -25,7 +25,6 @@ #include "src/core/tsi/alts/handshaker/alts_handshaker_client.h" static alts_shared_resource_dedicated g_alts_resource_dedicated; -static alts_shared_resource* g_shared_resources = alts_get_shared_resource(); alts_shared_resource_dedicated* grpc_alts_get_shared_resource_dedicated(void) { return &g_alts_resource_dedicated; @@ -49,16 +48,25 @@ static void thread_worker(void* arg) { void grpc_alts_shared_resource_dedicated_init() { g_alts_resource_dedicated.cq = nullptr; + gpr_mu_init(&g_alts_resource_dedicated.mu); } -void grpc_alts_shared_resource_dedicated_start() { - g_alts_resource_dedicated.cq = grpc_completion_queue_create_for_next(nullptr); - g_alts_resource_dedicated.thread = - grpc_core::Thread("alts_tsi_handshaker", &thread_worker, nullptr); - g_alts_resource_dedicated.interested_parties = grpc_pollset_set_create(); - grpc_pollset_set_add_pollset(g_alts_resource_dedicated.interested_parties, - grpc_cq_pollset(g_alts_resource_dedicated.cq)); - g_alts_resource_dedicated.thread.Start(); +void grpc_alts_shared_resource_dedicated_start( + const char* handshaker_service_url) { + gpr_mu_lock(&g_alts_resource_dedicated.mu); + if (g_alts_resource_dedicated.cq == nullptr) { + g_alts_resource_dedicated.channel = + grpc_insecure_channel_create(handshaker_service_url, nullptr, nullptr); + g_alts_resource_dedicated.cq = + grpc_completion_queue_create_for_next(nullptr); + g_alts_resource_dedicated.thread = + grpc_core::Thread("alts_tsi_handshaker", &thread_worker, nullptr); + g_alts_resource_dedicated.interested_parties = grpc_pollset_set_create(); + grpc_pollset_set_add_pollset(g_alts_resource_dedicated.interested_parties, + grpc_cq_pollset(g_alts_resource_dedicated.cq)); + g_alts_resource_dedicated.thread.Start(); + } + gpr_mu_unlock(&g_alts_resource_dedicated.mu); } void grpc_alts_shared_resource_dedicated_shutdown() { @@ -69,5 +77,7 @@ void grpc_alts_shared_resource_dedicated_shutdown() { g_alts_resource_dedicated.thread.Join(); grpc_pollset_set_destroy(g_alts_resource_dedicated.interested_parties); grpc_completion_queue_destroy(g_alts_resource_dedicated.cq); + grpc_channel_destroy(g_alts_resource_dedicated.channel); } + gpr_mu_destroy(&g_alts_resource_dedicated.mu); } diff --git a/src/core/tsi/alts/handshaker/alts_shared_resource.h b/src/core/tsi/alts/handshaker/alts_shared_resource.h index a07da305a85..8ae0089a11c 100644 --- a/src/core/tsi/alts/handshaker/alts_shared_resource.h +++ b/src/core/tsi/alts/handshaker/alts_shared_resource.h @@ -37,6 +37,8 @@ typedef struct alts_shared_resource_dedicated { grpc_completion_queue* cq; grpc_pollset_set* interested_parties; grpc_cq_completion storage; + gpr_mu mu; + grpc_channel* channel; } alts_shared_resource_dedicated; /* This method returns the address of alts_shared_resource_dedicated @@ -64,7 +66,8 @@ void grpc_alts_shared_resource_dedicated_init(); * The API will be invoked by the caller in a lazy manner. That is, * it will get invoked when ALTS TSI handshake occurs for the first time. */ -void grpc_alts_shared_resource_dedicated_start(); +void grpc_alts_shared_resource_dedicated_start( + const char* handshaker_service_url); #endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_SHARED_RESOURCE_H \ */ diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 16392528838..1b7e58d3ce0 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -39,9 +39,6 @@ #include "src/core/tsi/alts/handshaker/alts_shared_resource.h" #include "src/core/tsi/alts/handshaker/alts_tsi_utils.h" #include "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h" -#include "src/core/tsi/alts_transport_security.h" - -static alts_shared_resource* g_shared_resources = alts_get_shared_resource(); /* Main struct for ALTS TSI handshaker. */ struct alts_tsi_handshaker { @@ -51,11 +48,11 @@ struct alts_tsi_handshaker { bool is_client; bool has_sent_start_message; bool has_created_handshaker_client; - bool use_dedicated_cq; char* handshaker_service_url; grpc_pollset_set* interested_parties; grpc_alts_credentials_options* options; alts_handshaker_client_vtable* client_vtable_for_testing; + grpc_channel* channel; }; /* Main struct for ALTS TSI handshaker result. */ @@ -237,20 +234,6 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_handshaker_resp* resp, return TSI_OK; } -static void init_shared_resources(const char* handshaker_service_url, - bool use_dedicated_cq) { - GPR_ASSERT(handshaker_service_url != nullptr); - gpr_mu_lock(&g_shared_resources->mu); - if (g_shared_resources->channel == nullptr) { - g_shared_resources->channel = - grpc_insecure_channel_create(handshaker_service_url, nullptr, nullptr); - if (use_dedicated_cq) { - grpc_alts_shared_resource_dedicated_start(); - } - } - gpr_mu_unlock(&g_shared_resources->mu); -} - /* gRPC provided callback used when gRPC thread model is applied. */ static void on_handshaker_service_resp_recv(void* arg, grpc_error* error) { alts_handshaker_client* client = static_cast(arg); @@ -289,20 +272,24 @@ static tsi_result handshaker_next( reinterpret_cast(self); tsi_result ok = TSI_OK; if (!handshaker->has_created_handshaker_client) { - init_shared_resources(handshaker->handshaker_service_url, - handshaker->use_dedicated_cq); - if (handshaker->use_dedicated_cq) { + if (handshaker->channel == nullptr) { + grpc_alts_shared_resource_dedicated_start( + handshaker->handshaker_service_url); handshaker->interested_parties = grpc_alts_get_shared_resource_dedicated()->interested_parties; GPR_ASSERT(handshaker->interested_parties != nullptr); } - grpc_iomgr_cb_func grpc_cb = handshaker->use_dedicated_cq + grpc_iomgr_cb_func grpc_cb = handshaker->channel == nullptr ? on_handshaker_service_resp_recv_dedicated : on_handshaker_service_resp_recv; + grpc_channel* channel = + handshaker->channel == nullptr + ? grpc_alts_get_shared_resource_dedicated()->channel + : handshaker->channel; handshaker->client = alts_grpc_handshaker_client_create( - handshaker, g_shared_resources->channel, - handshaker->handshaker_service_url, handshaker->interested_parties, - handshaker->options, handshaker->target_name, grpc_cb, cb, user_data, + handshaker, channel, handshaker->handshaker_service_url, + handshaker->interested_parties, handshaker->options, + handshaker->target_name, grpc_cb, cb, user_data, handshaker->client_vtable_for_testing, handshaker->is_client); if (handshaker->client == nullptr) { gpr_log(GPR_ERROR, "Failed to create ALTS handshaker client"); @@ -310,7 +297,7 @@ static tsi_result handshaker_next( } handshaker->has_created_handshaker_client = true; } - if (handshaker->use_dedicated_cq && + if (handshaker->channel == nullptr && handshaker->client_vtable_for_testing == nullptr) { GPR_ASSERT(grpc_cq_begin_op(grpc_alts_get_shared_resource_dedicated()->cq, handshaker->client)); @@ -371,6 +358,9 @@ static void handshaker_destroy(tsi_handshaker* self) { alts_handshaker_client_destroy(handshaker->client); grpc_slice_unref_internal(handshaker->target_name); grpc_alts_credentials_options_destroy(handshaker->options); + if (handshaker->channel != nullptr) { + grpc_channel_destroy(handshaker->channel); + } gpr_free(handshaker->handshaker_service_url); gpr_free(handshaker); } @@ -407,7 +397,7 @@ tsi_result alts_tsi_handshaker_create( } alts_tsi_handshaker* handshaker = static_cast(gpr_zalloc(sizeof(*handshaker))); - handshaker->use_dedicated_cq = interested_parties == nullptr; + bool use_dedicated_cq = interested_parties == nullptr; handshaker->client = nullptr; handshaker->is_client = is_client; handshaker->has_sent_start_message = false; @@ -418,9 +408,13 @@ tsi_result alts_tsi_handshaker_create( handshaker->has_created_handshaker_client = false; handshaker->handshaker_service_url = gpr_strdup(handshaker_service_url); handshaker->options = grpc_alts_credentials_options_copy(options); - handshaker->base.vtable = handshaker->use_dedicated_cq - ? &handshaker_vtable_dedicated - : &handshaker_vtable; + handshaker->base.vtable = + use_dedicated_cq ? &handshaker_vtable_dedicated : &handshaker_vtable; + handshaker->channel = + use_dedicated_cq + ? nullptr + : grpc_insecure_channel_create(handshaker->handshaker_service_url, + nullptr, nullptr); *self = &handshaker->base; return TSI_OK; } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h index c961eae498d..32f94bc9d3f 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h @@ -27,7 +27,6 @@ #include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" #include "src/core/tsi/alts/handshaker/alts_handshaker_client.h" #include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h" -#include "src/core/tsi/alts_transport_security.h" #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc index ca861b52de2..078a917bbac 100644 --- a/src/core/tsi/transport_security.cc +++ b/src/core/tsi/transport_security.cc @@ -213,10 +213,10 @@ tsi_result tsi_handshaker_next( void tsi_handshaker_shutdown(tsi_handshaker* self) { if (self == nullptr || self->vtable == nullptr) return; - self->handshake_shutdown = true; if (self->vtable->shutdown != nullptr) { self->vtable->shutdown(self); } + self->handshake_shutdown = true; } void tsi_handshaker_destroy(tsi_handshaker* self) { diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 8e1cea0269d..d1c55319f7c 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -54,13 +54,11 @@ namespace grpc { static internal::GrpcLibraryInitializer g_gli_initializer; Channel::Channel( const grpc::string& host, grpc_channel* channel, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) : host_(host), c_channel_(channel) { - if (interceptor_creators != nullptr) { - interceptor_creators_ = std::move(*interceptor_creators); - } + interceptor_creators_ = std::move(interceptor_creators); g_gli_initializer.summon(); } 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; } diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index efdff6c2652..457daa674c7 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -39,13 +39,14 @@ std::shared_ptr CreateCustomChannel( const std::shared_ptr& creds, 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_lame_client_channel_create( - nullptr, GRPC_STATUS_INVALID_ARGUMENT, - "Invalid credentials."), - nullptr); + return creds ? creds->CreateChannel(target, args) + : CreateChannelInternal( + "", + grpc_lame_client_channel_create( + nullptr, GRPC_STATUS_INVALID_ARGUMENT, + "Invalid credentials."), + std::vector>()); } namespace experimental { @@ -64,17 +65,18 @@ std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, - std::unique_ptr>> + 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."), - nullptr); + 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>()); } } // namespace experimental diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index 313d682aae5..a0efb97f7ef 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -26,8 +26,8 @@ namespace grpc { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 512fc228669..a90c92c518d 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -31,8 +31,8 @@ class Channel; std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators); } // namespace grpc diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 8d775e7a87f..3affc1ef391 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -34,7 +34,8 @@ std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, init_lib.init(); return CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), - nullptr); + std::vector< + std::unique_ptr>()); } std::shared_ptr CreateCustomInsecureChannelFromFd( @@ -46,15 +47,16 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( return CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), - nullptr); + std::vector< + std::unique_ptr>()); } namespace experimental { std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( const grpc::string& target, int fd, const ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) { internal::GrpcLibrary init_lib; init_lib.init(); diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 09a76b428cc..b2801764f20 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -31,7 +31,10 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { std::shared_ptr CreateChannel( const string& target, const grpc::ChannelArguments& args) override { - return CreateChannelWithInterceptors(target, args, nullptr); + return CreateChannelWithInterceptors( + target, args, + std::vector>()); } SecureChannelCredentials* AsSecureCredentials() override { return nullptr; } @@ -39,8 +42,8 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { private: std::shared_ptr CreateChannelWithInterceptors( const string& target, const grpc::ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index b816e0c59af..241ce918034 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -32,13 +32,16 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: std::shared_ptr CreateChannel( const string& target, const grpc::ChannelArguments& args) override { - return CreateChannelWithInterceptors(target, args, nullptr); + return CreateChannelWithInterceptors( + target, args, + std::vector>()); } std::shared_ptr CreateChannelWithInterceptors( const string& target, const grpc::ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 7faaa20e782..d0abe441a6a 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -36,14 +36,17 @@ SecureChannelCredentials::SecureChannelCredentials( std::shared_ptr SecureChannelCredentials::CreateChannel( const string& target, const grpc::ChannelArguments& args) { - return CreateChannelWithInterceptors(target, args, nullptr); + return CreateChannelWithInterceptors( + target, args, + std::vector< + std::unique_ptr>()); } std::shared_ptr SecureChannelCredentials::CreateChannelWithInterceptors( const string& target, const grpc::ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index bfb6e17ee9d..613f1d6dc2c 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -42,8 +42,8 @@ class SecureChannelCredentials final : public ChannelCredentials { private: std::shared_ptr CreateChannelWithInterceptors( const string& target, const grpc::ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; 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/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index c031528a8f3..0a51cf5626e 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -58,6 +58,9 @@ namespace { // max-threads set) to the server builder. #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 + class DefaultGlobalCallbacks final : public Server::GlobalCallbacks { public: ~DefaultGlobalCallbacks() override {} @@ -81,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 { @@ -199,9 +199,21 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { } } + 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; @@ -586,7 +598,17 @@ class Server::SyncRequestThreadManager : public ThreadManager { void* tag; bool ok; while (server_cq_->Next(&tag, &ok)) { - // Do nothing + 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(); + } } } @@ -707,14 +729,15 @@ std::shared_ptr Server::InProcessChannel( grpc_channel_args channel_args = args.c_channel_args(); return CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), - nullptr); + std::vector< + std::unique_ptr>()); } std::shared_ptr Server::experimental_type::InProcessChannelWithInterceptors( const ChannelArguments& args, - std::unique_ptr>> + std::vector< + std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args = args.c_channel_args(); return CreateChannelInternal( @@ -769,9 +792,12 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { (*it)->AddSyncMethod(method, method_registration_tag); } } else { - // a callback method - auto* req = new CallbackRequest(this, method, method_registration_tag); - callback_reqs_.emplace_back(req); + // a callback method. Register at least some callback requests + // 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); + } // Enqueue it so that it will be Request'ed later once // all request matchers are created at core server startup } diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 396996e5bc6..9c01f896e6c 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -247,6 +247,10 @@ void ServerContext::BindDeadlineAndMetadata(gpr_timespec deadline, ServerContext::~ServerContext() { Clear(); } void ServerContext::Clear() { + auth_context_.reset(); + initial_metadata_.clear(); + trailing_metadata_.clear(); + client_metadata_.Reset(); if (call_) { grpc_call_unref(call_); } diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs index e7d89399789..5c7d48f786c 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs @@ -49,7 +49,7 @@ namespace Grpc.Core.Internal.Tests fakeCall = new FakeNativeCall(); asyncCallServer = new AsyncCallServer( - Marshallers.StringMarshaller.Serializer, Marshallers.StringMarshaller.Deserializer, + Marshallers.StringMarshaller.ContextualSerializer, Marshallers.StringMarshaller.ContextualDeserializer, server); asyncCallServer.InitializeForTesting(fakeCall); } diff --git a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs index 97f64a0575e..ad3e81d61f6 100644 --- a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs +++ b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs @@ -69,11 +69,8 @@ namespace Grpc.Core.Tests Assert.AreSame(contextualSerializer, marshaller.ContextualSerializer); Assert.AreSame(contextualDeserializer, marshaller.ContextualDeserializer); - - // test that emulated serializer and deserializer work - var origMsg = "abc"; - var serialized = marshaller.Serializer(origMsg); - Assert.AreEqual(origMsg, marshaller.Deserializer(serialized)); + Assert.Throws(typeof(NotImplementedException), () => marshaller.Serializer("abc")); + Assert.Throws(typeof(NotImplementedException), () => marshaller.Deserializer(new byte[] {1, 2, 3})); } class FakeSerializationContext : SerializationContext diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core/DeserializationContext.cs index 5b6372ef85d..d69e0db5bdf 100644 --- a/src/csharp/Grpc.Core/DeserializationContext.cs +++ b/src/csharp/Grpc.Core/DeserializationContext.cs @@ -16,6 +16,8 @@ #endregion +using System; + namespace Grpc.Core { /// @@ -41,6 +43,9 @@ namespace Grpc.Core /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. /// /// byte array containing the entire payload. - public abstract byte[] PayloadAsNewBuffer(); + public virtual byte[] PayloadAsNewBuffer() + { + throw new NotImplementedException(); + } } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 4cdf0ee6a72..b6d687f71e7 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -54,7 +54,7 @@ namespace Grpc.Core.Internal ClientSideStatus? finishedStatus; public AsyncCall(CallInvocationDetails callDetails) - : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer) + : base(callDetails.RequestMarshaller.ContextualSerializer, callDetails.ResponseMarshaller.ContextualDeserializer) { this.details = callDetails.WithOptions(callDetails.Options.Normalize()); this.initialMetadataSent = true; // we always send metadata at the very beginning of the call. diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index a93dc346205..39c9f7c6160 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -40,8 +40,8 @@ namespace Grpc.Core.Internal static readonly ILogger Logger = GrpcEnvironment.Logger.ForType>(); protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message."); - readonly Func serializer; - readonly Func deserializer; + readonly Action serializer; + readonly Func deserializer; protected readonly object myLock = new object(); @@ -63,7 +63,7 @@ namespace Grpc.Core.Internal protected bool initialMetadataSent; protected long streamingWritesCounter; // Number of streaming send operations started so far. - public AsyncCallBase(Func serializer, Func deserializer) + public AsyncCallBase(Action serializer, Func deserializer) { this.serializer = GrpcPreconditions.CheckNotNull(serializer); this.deserializer = GrpcPreconditions.CheckNotNull(deserializer); @@ -215,14 +215,26 @@ namespace Grpc.Core.Internal protected byte[] UnsafeSerialize(TWrite msg) { - return serializer(msg); + DefaultSerializationContext context = null; + try + { + context = DefaultSerializationContext.GetInitializedThreadLocal(); + serializer(msg, context); + return context.GetPayload(); + } + finally + { + context?.Reset(); + } } protected Exception TryDeserialize(byte[] payload, out TRead msg) { + DefaultDeserializationContext context = null; try { - msg = deserializer(payload); + context = DefaultDeserializationContext.GetInitializedThreadLocal(payload); + msg = deserializer(context); return null; } catch (Exception e) @@ -230,6 +242,11 @@ namespace Grpc.Core.Internal msg = default(TRead); return e; } + finally + { + context?.Reset(); + + } } /// diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs index 0ceca4abb8f..0bf1fb3b7dd 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs @@ -37,7 +37,7 @@ namespace Grpc.Core.Internal readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); readonly Server server; - public AsyncCallServer(Func serializer, Func deserializer, Server server) : base(serializer, deserializer) + public AsyncCallServer(Action serializer, Func deserializer, Server server) : base(serializer, deserializer) { this.server = GrpcPreconditions.CheckNotNull(server); } diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs new file mode 100644 index 00000000000..7ace80e8d53 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs @@ -0,0 +1,66 @@ +#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 Grpc.Core.Utils; +using System; +using System.Threading; + +namespace Grpc.Core.Internal +{ + internal class DefaultDeserializationContext : DeserializationContext + { + static readonly ThreadLocal threadLocalInstance = + new ThreadLocal(() => new DefaultDeserializationContext(), false); + + byte[] payload; + bool alreadyCalledPayloadAsNewBuffer; + + public DefaultDeserializationContext() + { + Reset(); + } + + public override int PayloadLength => payload.Length; + + public override byte[] PayloadAsNewBuffer() + { + GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer); + alreadyCalledPayloadAsNewBuffer = true; + return payload; + } + + public void Initialize(byte[] payload) + { + this.payload = GrpcPreconditions.CheckNotNull(payload); + this.alreadyCalledPayloadAsNewBuffer = false; + } + + public void Reset() + { + this.payload = null; + this.alreadyCalledPayloadAsNewBuffer = true; // mark payload as read + } + + public static DefaultDeserializationContext GetInitializedThreadLocal(byte[] payload) + { + var instance = threadLocalInstance.Value; + instance.Initialize(payload); + return instance; + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs new file mode 100644 index 00000000000..cceb194879e --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs @@ -0,0 +1,62 @@ +#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 Grpc.Core.Utils; +using System.Threading; + +namespace Grpc.Core.Internal +{ + internal class DefaultSerializationContext : SerializationContext + { + static readonly ThreadLocal threadLocalInstance = + new ThreadLocal(() => new DefaultSerializationContext(), false); + + bool isComplete; + byte[] payload; + + public DefaultSerializationContext() + { + Reset(); + } + + public override void Complete(byte[] payload) + { + GrpcPreconditions.CheckState(!isComplete); + this.isComplete = true; + this.payload = payload; + } + + internal byte[] GetPayload() + { + return this.payload; + } + + public void Reset() + { + this.isComplete = false; + this.payload = null; + } + + public static DefaultSerializationContext GetInitializedThreadLocal() + { + var instance = threadLocalInstance.Value; + instance.Reset(); + return instance; + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index 81522cf8fef..ec732e8c7f4 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -52,8 +52,8 @@ namespace Grpc.Core.Internal public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer( - method.ResponseMarshaller.Serializer, - method.RequestMarshaller.Deserializer, + method.ResponseMarshaller.ContextualSerializer, + method.RequestMarshaller.ContextualDeserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); @@ -116,8 +116,8 @@ namespace Grpc.Core.Internal public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer( - method.ResponseMarshaller.Serializer, - method.RequestMarshaller.Deserializer, + method.ResponseMarshaller.ContextualSerializer, + method.RequestMarshaller.ContextualDeserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); @@ -179,8 +179,8 @@ namespace Grpc.Core.Internal public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer( - method.ResponseMarshaller.Serializer, - method.RequestMarshaller.Deserializer, + method.ResponseMarshaller.ContextualSerializer, + method.RequestMarshaller.ContextualDeserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); @@ -242,8 +242,8 @@ namespace Grpc.Core.Internal public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer( - method.ResponseMarshaller.Serializer, - method.RequestMarshaller.Deserializer, + method.ResponseMarshaller.ContextualSerializer, + method.RequestMarshaller.ContextualDeserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index 0af9aa586bf..34a1849cd74 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -41,6 +41,8 @@ namespace Grpc.Core { this.serializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer)); this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer)); + // contextual serialization/deserialization is emulated to make the marshaller + // usable with the grpc library (required for backward compatibility). this.contextualSerializer = EmulateContextualSerializer; this.contextualDeserializer = EmulateContextualDeserializer; } @@ -57,10 +59,10 @@ namespace Grpc.Core { this.contextualSerializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer)); this.contextualDeserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer)); - // TODO(jtattermusch): once gRPC C# library switches to using contextual (de)serializer, - // emulating the simple (de)serializer will become unnecessary. - this.serializer = EmulateSimpleSerializer; - this.deserializer = EmulateSimpleDeserializer; + // gRPC only uses contextual serializer/deserializer internally, so emulating the legacy + // (de)serializer is not necessary. + this.serializer = (msg) => { throw new NotImplementedException(); }; + this.deserializer = (payload) => { throw new NotImplementedException(); }; } /// @@ -85,25 +87,6 @@ namespace Grpc.Core /// public Func ContextualDeserializer => this.contextualDeserializer; - // for backward compatibility, emulate the simple serializer using the contextual one - private byte[] EmulateSimpleSerializer(T msg) - { - // TODO(jtattermusch): avoid the allocation by passing a thread-local instance - // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer. - var context = new EmulatedSerializationContext(); - this.contextualSerializer(msg, context); - return context.GetPayload(); - } - - // for backward compatibility, emulate the simple deserializer using the contextual one - private T EmulateSimpleDeserializer(byte[] payload) - { - // TODO(jtattermusch): avoid the allocation by passing a thread-local instance - // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer. - var context = new EmulatedDeserializationContext(payload); - return this.contextualDeserializer(context); - } - // for backward compatibility, emulate the contextual serializer using the simple one private void EmulateContextualSerializer(T message, SerializationContext context) { @@ -116,44 +99,6 @@ namespace Grpc.Core { return this.deserializer(context.PayloadAsNewBuffer()); } - - internal class EmulatedSerializationContext : SerializationContext - { - bool isComplete; - byte[] payload; - - public override void Complete(byte[] payload) - { - GrpcPreconditions.CheckState(!isComplete); - this.isComplete = true; - this.payload = payload; - } - - internal byte[] GetPayload() - { - return this.payload; - } - } - - internal class EmulatedDeserializationContext : DeserializationContext - { - readonly byte[] payload; - bool alreadyCalledPayloadAsNewBuffer; - - public EmulatedDeserializationContext(byte[] payload) - { - this.payload = GrpcPreconditions.CheckNotNull(payload); - } - - public override int PayloadLength => payload.Length; - - public override byte[] PayloadAsNewBuffer() - { - GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer); - alreadyCalledPayloadAsNewBuffer = true; - return payload; - } - } } /// diff --git a/src/csharp/Grpc.Core/SerializationContext.cs b/src/csharp/Grpc.Core/SerializationContext.cs index cf4d1595da2..9aef2adbcd5 100644 --- a/src/csharp/Grpc.Core/SerializationContext.cs +++ b/src/csharp/Grpc.Core/SerializationContext.cs @@ -16,6 +16,8 @@ #endregion +using System; + namespace Grpc.Core { /// @@ -29,6 +31,9 @@ namespace Grpc.Core /// payload which must not be accessed afterwards. /// /// the serialized form of current message - public abstract void Complete(byte[] payload); + public virtual void Complete(byte[] payload) + { + throw new NotImplementedException(); + } } } diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs index 07c6aa17967..b040ab379c8 100644 --- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs +++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs @@ -72,7 +72,7 @@ namespace Grpc.Core } /// - /// Adds a definitions for a single request - single response method. + /// Adds a definition for a single request - single response method. /// /// The request message class. /// The response message class. @@ -90,7 +90,7 @@ namespace Grpc.Core } /// - /// Adds a definitions for a client streaming method. + /// Adds a definition for a client streaming method. /// /// The request message class. /// The response message class. @@ -108,7 +108,7 @@ namespace Grpc.Core } /// - /// Adds a definitions for a server streaming method. + /// Adds a definition for a server streaming method. /// /// The request message class. /// The response message class. @@ -126,7 +126,7 @@ namespace Grpc.Core } /// - /// Adds a definitions for a bidirectional streaming method. + /// Adds a definition for a bidirectional streaming method. /// /// The request message class. /// The response message class. diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core/ServiceBinderBase.cs new file mode 100644 index 00000000000..d4909f4a269 --- /dev/null +++ b/src/csharp/Grpc.Core/ServiceBinderBase.cs @@ -0,0 +1,101 @@ +#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.Collections.ObjectModel; +using System.Linq; +using Grpc.Core.Interceptors; +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +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 + { + /// + /// 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(); + } + } +} 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/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 9578bb4d811..e5be387e67e 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -287,6 +287,18 @@ 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); + } + } } #endregion diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs index a90f261d286..2c3bb45c3cf 100644 --- a/src/csharp/Grpc.HealthCheck/Health.cs +++ b/src/csharp/Grpc.HealthCheck/Health.cs @@ -25,15 +25,17 @@ namespace Grpc.Health.V1 { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "ChtncnBjL2hlYWx0aC92MS9oZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYx", - "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNI", + "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIqkBChNI", "ZWFsdGhDaGVja1Jlc3BvbnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVh", - "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1T", + "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyJPCg1T", "ZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9U", - "X1NFUlZJTkcQAjJaCgZIZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52", - "MS5IZWFsdGhDaGVja1JlcXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhD", - "aGVja1Jlc3BvbnNlQmEKEWlvLmdycGMuaGVhbHRoLnYxQgtIZWFsdGhQcm90", - "b1ABWixnb29nbGUuZ29sYW5nLm9yZy9ncnBjL2hlYWx0aC9ncnBjX2hlYWx0", - "aF92MaoCDkdycGMuSGVhbHRoLlYxYgZwcm90bzM=")); + "X1NFUlZJTkcQAhITCg9TRVJWSUNFX1VOS05PV04QAzKuAQoGSGVhbHRoElAK", + "BUNoZWNrEiIuZ3JwYy5oZWFsdGgudjEuSGVhbHRoQ2hlY2tSZXF1ZXN0GiMu", + "Z3JwYy5oZWFsdGgudjEuSGVhbHRoQ2hlY2tSZXNwb25zZRJSCgVXYXRjaBIi", + "LmdycGMuaGVhbHRoLnYxLkhlYWx0aENoZWNrUmVxdWVzdBojLmdycGMuaGVh", + "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UwAUJhChFpby5ncnBjLmhlYWx0", + "aC52MUILSGVhbHRoUHJvdG9QAVosZ29vZ2xlLmdvbGFuZy5vcmcvZ3JwYy9o", + "ZWFsdGgvZ3JwY19oZWFsdGhfdjGqAg5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { @@ -309,6 +311,10 @@ namespace Grpc.Health.V1 { [pbr::OriginalName("UNKNOWN")] Unknown = 0, [pbr::OriginalName("SERVING")] Serving = 1, [pbr::OriginalName("NOT_SERVING")] NotServing = 2, + /// + /// Used only by the Watch method. + /// + [pbr::OriginalName("SERVICE_UNKNOWN")] ServiceUnknown = 3, } } diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 5e79c04d2a5..51956f2f234 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -40,6 +40,13 @@ namespace Grpc.Health.V1 { __Marshaller_grpc_health_v1_HealthCheckRequest, __Marshaller_grpc_health_v1_HealthCheckResponse); + static readonly grpc::Method __Method_Watch = new grpc::Method( + grpc::MethodType.ServerStreaming, + __ServiceName, + "Watch", + __Marshaller_grpc_health_v1_HealthCheckRequest, + __Marshaller_grpc_health_v1_HealthCheckResponse); + /// Service descriptor public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor { @@ -49,11 +56,44 @@ namespace Grpc.Health.V1 { /// Base class for server-side implementations of Health public abstract partial class HealthBase { + /// + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. + /// + /// 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 Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::ServerCallContext context) { throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); } + /// + /// 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. + /// + /// 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 Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) + { + throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); + } + } /// Client for Health @@ -79,22 +119,104 @@ namespace Grpc.Health.V1 { { } + /// + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. + /// + /// 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::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return Check(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } + /// + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. + /// + /// The request to send to the server. + /// The options for the call. + /// The response received from the server. public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options) { return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request); } + /// + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. + /// + /// 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 CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return CheckAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } + /// + /// If the requested service is unknown, the call will fail with status + /// NOT_FOUND. + /// + /// The request to send to the server. + /// The options for the call. + /// The call object. public virtual grpc::AsyncUnaryCall CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options) { return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request); } + /// + /// 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. + /// + /// 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 Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + { + return Watch(request, new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// 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. + /// + /// The request to send to the server. + /// The options for the call. + /// The call object. + public virtual grpc::AsyncServerStreamingCall Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options) + { + return CallInvoker.AsyncServerStreamingCall(__Method_Watch, null, options, request); + } /// Creates a new instance of client from given ClientBaseConfiguration. protected override HealthClient NewInstance(ClientBaseConfiguration configuration) { @@ -107,7 +229,18 @@ namespace Grpc.Health.V1 { public static grpc::ServerServiceDefinition BindService(HealthBase serviceImpl) { return grpc::ServerServiceDefinition.CreateBuilder() - .AddMethod(__Method_Check, serviceImpl.Check).Build(); + .AddMethod(__Method_Check, serviceImpl.Check) + .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); } } diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index b5738593f26..3431b5fa181 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -324,6 +324,19 @@ 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); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index 6e003484513..368b86659a5 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -34,7 +34,7 @@ namespace Grpc.Testing { "U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy", "X2hvc3Rfb3ZlcnJpZGUYAiABKAkSEQoJY3JlZF90eXBlGAMgASgJIk0KCkNo", "YW5uZWxBcmcSDAoEbmFtZRgBIAEoCRITCglzdHJfdmFsdWUYAiABKAlIABIT", - "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSLvBAoMQ2xpZW50Q29uZmln", + "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSKiBQoMQ2xpZW50Q29uZmln", "EhYKDnNlcnZlcl90YXJnZXRzGAEgAygJEi0KC2NsaWVudF90eXBlGAIgASgO", "MhguZ3JwYy50ZXN0aW5nLkNsaWVudFR5cGUSNQoPc2VjdXJpdHlfcGFyYW1z", "GAMgASgLMhwuZ3JwYy50ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEiQKHG91dHN0", @@ -48,59 +48,60 @@ namespace Grpc.Testing { "GA4gASgFEhgKEG90aGVyX2NsaWVudF9hcGkYDyABKAkSLgoMY2hhbm5lbF9h", "cmdzGBAgAygLMhguZ3JwYy50ZXN0aW5nLkNoYW5uZWxBcmcSFgoOdGhyZWFk", "c19wZXJfY3EYESABKAUSGwoTbWVzc2FnZXNfcGVyX3N0cmVhbRgSIAEoBRIY", - "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIIjgKDENsaWVudFN0YXR1cxIoCgVz", - "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr", - "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy", - "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS", - "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2VydmVyQ29u", - "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl", - "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n", - "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy", - "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk", - "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK", - "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhYK", - "DnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3RhX3NpemUY", - "6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRlc3Rpbmcu", - "Q2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgLMhouZ3Jw", - "Yy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBj", - "LnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3RhdHVzEigK", - "BXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEgwKBHBv", - "cnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3QiHQoMQ29y", - "ZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNjZW5hcmlv", - "EgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIaLmdycGMu", - "dGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyABKAUSMQoN", - "c2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJDb25m", - "aWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29uZHMYBiAB", - "KAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25fbG9jYWxf", - "d29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2VuYXJpb3MY", - "ASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5hcmlvUmVz", - "dWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2ZXJfY29y", - "ZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQc2VydmVy", - "X3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUYBSABKAES", - "GAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUwGAcgASgB", - "EhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEoARISCgps", - "YXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgKEHNlcnZl", - "cl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0c19wZXJf", - "c2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vjb25kGA4g", - "ASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIgChhzZXJ2", - "ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1ZXJpZXNf", - "cGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVyX2NwdV9z", - "ZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlvGAEgASgL", - "MhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgCIAEoCzIb", - "LmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9zdGF0cxgD", - "IAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2ZXJfc3Rh", - "dHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoMc2VydmVy", - "X2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRlc3Rpbmcu", - "U2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNzGAcgAygI", - "EhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVzdWx0cxgJ", - "IAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQqQQoKQ2xp", - "ZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVOVBABEhAK", - "DE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQ", - "ABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhAC", - "EhAKDE9USEVSX1NFUlZFUhADKnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglT", - "VFJFQU1JTkcQARIZChVTVFJFQU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJF", - "QU1JTkdfRlJPTV9TRVJWRVIQAxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARi", - "BnByb3RvMw==")); + "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIEjEKKW1lZGlhbl9sYXRlbmN5X2Nv", + "bGxlY3Rpb25faW50ZXJ2YWxfbWlsbGlzGBQgASgFIjgKDENsaWVudFN0YXR1", + "cxIoCgVzdGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIV", + "CgRNYXJrEg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAY", + "ASABKAsyGi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgC", + "IAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2Vy", + "dmVyQ29uZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5n", + "LlNlcnZlclR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50", + "ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNf", + "c2VydmVyX3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5w", + "YXlsb2FkX2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29u", + "ZmlnEhEKCWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsg", + "ASgJEhYKDnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3Rh", + "X3NpemUY6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRl", + "c3RpbmcuQ2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgL", + "MhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsy", + "Ei5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3Rh", + "dHVzEigKBXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRz", + "EgwKBHBvcnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3Qi", + "HQoMQ29yZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNj", + "ZW5hcmlvEgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIa", + "LmdycGMudGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyAB", + "KAUSMQoNc2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2", + "ZXJDb25maWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29u", + "ZHMYBiABKAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25f", + "bG9jYWxfd29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2Vu", + "YXJpb3MYASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5h", + "cmlvUmVzdWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2", + "ZXJfY29yZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQ", + "c2VydmVyX3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUY", + "BSABKAESGAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUw", + "GAcgASgBEhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEo", + "ARISCgpsYXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgK", + "EHNlcnZlcl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0", + "c19wZXJfc2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vj", + "b25kGA4gASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIg", + "ChhzZXJ2ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1", + "ZXJpZXNfcGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVy", + "X2NwdV9zZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlv", + "GAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgC", + "IAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9z", + "dGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2", + "ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoM", + "c2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRl", + "c3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNz", + "GAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVz", + "dWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQq", + "VgoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVO", + "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKlsK", + "ClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQ", + "ARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhAD", + "KnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1JTkcQARIZChVTVFJF", + "QU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJFQU1JTkdfRlJPTV9TRVJWRVIQ", + "AxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARiBnByb3RvMw==")); 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[] { @@ -109,7 +110,7 @@ namespace Grpc.Testing { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride", "CredType" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi", "MedianLatencyCollectionIntervalMillis" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null), @@ -140,6 +141,7 @@ namespace Grpc.Testing { /// used for some language-specific variants /// [pbr::OriginalName("OTHER_CLIENT")] OtherClient = 2, + [pbr::OriginalName("CALLBACK_CLIENT")] CallbackClient = 3, } public enum ServerType { @@ -1054,6 +1056,7 @@ namespace Grpc.Testing { threadsPerCq_ = other.threadsPerCq_; messagesPerStream_ = other.messagesPerStream_; useCoalesceApi_ = other.useCoalesceApi_; + medianLatencyCollectionIntervalMillis_ = other.medianLatencyCollectionIntervalMillis_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -1278,6 +1281,21 @@ namespace Grpc.Testing { } } + /// Field number for the "median_latency_collection_interval_millis" field. + public const int MedianLatencyCollectionIntervalMillisFieldNumber = 20; + private int medianLatencyCollectionIntervalMillis_; + /// + /// If 0, disabled. Else, specifies the period between gathering latency + /// medians in milliseconds. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int MedianLatencyCollectionIntervalMillis { + get { return medianLatencyCollectionIntervalMillis_; } + set { + medianLatencyCollectionIntervalMillis_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientConfig); @@ -1308,6 +1326,7 @@ namespace Grpc.Testing { if (ThreadsPerCq != other.ThreadsPerCq) return false; if (MessagesPerStream != other.MessagesPerStream) return false; if (UseCoalesceApi != other.UseCoalesceApi) return false; + if (MedianLatencyCollectionIntervalMillis != other.MedianLatencyCollectionIntervalMillis) return false; return Equals(_unknownFields, other._unknownFields); } @@ -1331,6 +1350,7 @@ namespace Grpc.Testing { if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode(); if (MessagesPerStream != 0) hash ^= MessagesPerStream.GetHashCode(); if (UseCoalesceApi != false) hash ^= UseCoalesceApi.GetHashCode(); + if (MedianLatencyCollectionIntervalMillis != 0) hash ^= MedianLatencyCollectionIntervalMillis.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -1403,6 +1423,10 @@ namespace Grpc.Testing { output.WriteRawTag(152, 1); output.WriteBool(UseCoalesceApi); } + if (MedianLatencyCollectionIntervalMillis != 0) { + output.WriteRawTag(160, 1); + output.WriteInt32(MedianLatencyCollectionIntervalMillis); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -1456,6 +1480,9 @@ namespace Grpc.Testing { if (UseCoalesceApi != false) { size += 2 + 1; } + if (MedianLatencyCollectionIntervalMillis != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(MedianLatencyCollectionIntervalMillis); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -1524,6 +1551,9 @@ namespace Grpc.Testing { if (other.UseCoalesceApi != false) { UseCoalesceApi = other.UseCoalesceApi; } + if (other.MedianLatencyCollectionIntervalMillis != 0) { + MedianLatencyCollectionIntervalMillis = other.MedianLatencyCollectionIntervalMillis; + } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1616,6 +1646,10 @@ namespace Grpc.Testing { UseCoalesceApi = input.ReadBool(); break; } + case 160: { + MedianLatencyCollectionIntervalMillis = input.ReadInt32(); + break; + } } } } diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index 2d233fbdc0e..7e77f8d1141 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -80,6 +80,14 @@ 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) + { + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 9f16f41ac1e..c66a9a9161e 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -193,6 +193,16 @@ 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); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index 1da0548cb43..954c1722723 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -143,6 +143,15 @@ 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); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index 2176916b430..d125fd5627b 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -539,6 +539,22 @@ 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); + } + } /// /// A simple service NOT implemented at servers so clients can test for @@ -661,6 +677,15 @@ 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); + } + } /// /// A service used to control reconnect server. @@ -779,6 +804,16 @@ 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); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index b9e8f912314..5b22337d533 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -321,6 +321,18 @@ 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); + } + } } #endregion diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index c00075b7c69..ed55c2f584f 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -123,6 +123,15 @@ 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); + } + } } #endregion 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/channel.c b/src/php/ext/grpc/channel.c index b17f3d9a613..c06bdea7feb 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -393,6 +393,8 @@ PHP_METHOD(Channel, __construct) { channel->wrapper->target = strdup(target); channel->wrapper->args_hashstr = strdup(sha1str); channel->wrapper->creds_hashstr = NULL; + channel->wrapper->creds = creds; + channel->wrapper->args = args; if (creds != NULL && creds->hashstr != NULL) { php_grpc_int creds_hashstr_len = strlen(creds->hashstr); char *channel_creds_hashstr = malloc(creds_hashstr_len + 1); diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h index 27752c9a3f0..ce17c4a58a7 100644 --- a/src/php/ext/grpc/channel.h +++ b/src/php/ext/grpc/channel.h @@ -19,6 +19,7 @@ #ifndef NET_GRPC_PHP_GRPC_CHANNEL_H_ #define NET_GRPC_PHP_GRPC_CHANNEL_H_ +#include "channel_credentials.h" #include "php_grpc.h" /* Class entry for the PHP Channel class */ @@ -32,6 +33,8 @@ typedef struct _grpc_channel_wrapper { char *creds_hashstr; size_t ref_count; gpr_mu mu; + grpc_channel_args args; + wrapped_grpc_channel_credentials *creds; } grpc_channel_wrapper; /* Wrapper struct for grpc_channel that can be associated with a PHP object */ diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4 index fa54ebd9200..9ec2c7cf04c 100755 --- a/src/php/ext/grpc/config.m4 +++ b/src/php/ext/grpc/config.m4 @@ -103,7 +103,7 @@ if test "$PHP_COVERAGE" = "yes"; then AC_MSG_ERROR([ccache must be disabled when --enable-coverage option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) fi - lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11" + lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11 1.12 1.13" AC_CHECK_PROG(LCOV, lcov, lcov) AC_CHECK_PROG(GENHTML, genhtml, genhtml) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index fabd98975df..111c6f4867d 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -26,6 +26,8 @@ #include "call_credentials.h" #include "server_credentials.h" #include "completion_queue.h" +#include +#include ZEND_DECLARE_MODULE_GLOBALS(grpc) static PHP_GINIT_FUNCTION(grpc); @@ -86,6 +88,125 @@ ZEND_GET_MODULE(grpc) } */ /* }}} */ +void create_new_channel( + wrapped_grpc_channel *channel, + char *target, + grpc_channel_args args, + wrapped_grpc_channel_credentials *creds) { + if (creds == NULL) { + channel->wrapper->wrapped = grpc_insecure_channel_create(target, &args, + NULL); + } else { + channel->wrapper->wrapped = + grpc_secure_channel_create(creds->wrapped, target, &args, NULL); + } +} + +void acquire_persistent_locks() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + gpr_mu_lock(&le->channel->mu); + PHP_GRPC_HASH_FOREACH_END() +} + +void release_persistent_locks() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + gpr_mu_unlock(&le->channel->mu); + PHP_GRPC_HASH_FOREACH_END() +} + +void destroy_grpc_channels() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + wrapped_grpc_channel wrapped_channel; + wrapped_channel.wrapper = le->channel; + grpc_channel_wrapper *channel = wrapped_channel.wrapper; + grpc_channel_destroy(channel->wrapped); + PHP_GRPC_HASH_FOREACH_END() +} + +void restart_channels() { + zval *data; + PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data) + php_grpc_zend_resource *rsrc = + (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data) + if (rsrc == NULL) { + break; + } + channel_persistent_le_t* le = rsrc->ptr; + + wrapped_grpc_channel wrapped_channel; + wrapped_channel.wrapper = le->channel; + grpc_channel_wrapper *channel = wrapped_channel.wrapper; + create_new_channel(&wrapped_channel, channel->target, channel->args, + channel->creds); + gpr_mu_unlock(&channel->mu); + PHP_GRPC_HASH_FOREACH_END() +} + +void prefork() { + acquire_persistent_locks(); +} + +void postfork_child() { + TSRMLS_FETCH(); + + // loop through persistant list and destroy all underlying grpc_channel objs + destroy_grpc_channels(); + + // clear completion queue + grpc_php_shutdown_completion_queue(TSRMLS_C); + + // clean-up grpc_core + grpc_shutdown(); + if (grpc_is_initialized() > 0) { + zend_throw_exception(spl_ce_UnexpectedValueException, + "Oops, failed to shutdown gRPC Core after fork()", + 1 TSRMLS_CC); + } + + // restart grpc_core + grpc_init(); + grpc_php_init_completion_queue(TSRMLS_C); + + // re-create grpc_channel and point wrapped to it + // unlock wrapped grpc channel mutex + restart_channels(); +} + +void postfork_parent() { + release_persistent_locks(); +} + +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 + } +} /* {{{ PHP_MINIT_FUNCTION */ @@ -265,6 +386,7 @@ PHP_MINFO_FUNCTION(grpc) { PHP_RINIT_FUNCTION(grpc) { if (!GRPC_G(initialized)) { grpc_init(); + register_fork_handlers(); grpc_php_init_completion_queue(TSRMLS_C); GRPC_G(initialized) = 1; } 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/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/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; 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'), diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index df98dd10ad1..6022fc3ef21 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -15,12 +15,14 @@ import abc import enum +import logging import sys - import six from grpc._cython import cygrpc as _cygrpc +logging.getLogger(__name__).addHandler(logging.NullHandler()) + ############################## Future Interface ############################### @@ -387,7 +389,8 @@ class ClientCallDetails(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready mechanism. + wait_for_ready: This is an EXPERIMENTAL argument. An optional flag t + enable wait for ready mechanism. """ @@ -654,8 +657,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: The response value for the RPC. @@ -683,8 +686,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: The response value for the RPC and a Call value for the RPC. @@ -712,8 +715,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: An object that is both a Call for the RPC and a Future. @@ -744,8 +747,8 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: An optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: An object that is both a Call for the RPC and an iterator of @@ -776,8 +779,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: The response value for the RPC. @@ -806,8 +809,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: The response value for the RPC and a Call object for the RPC. @@ -835,8 +838,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: An object that is both a Call for the RPC and a Future. @@ -867,8 +870,8 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. credentials: An optional CallCredentials for the RPC. - wait_for_ready: An optional flag to enable wait for ready - mechanism + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable wait for ready mechanism Returns: An object that is both a Call for the RPC and an iterator of @@ -1720,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. diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 3ff76587484..ab154d85121 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -25,7 +25,6 @@ from grpc._cython import cygrpc from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) _USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__) diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py index 42f3a4e6147..f69127e38ef 100644 --- a/src/python/grpcio/grpc/_common.py +++ b/src/python/grpcio/grpc/_common.py @@ -21,7 +21,6 @@ import grpc from grpc._cython import cygrpc _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = { cygrpc.ConnectivityState.idle: 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..113f7976dd9 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi @@ -0,0 +1,69 @@ +# 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/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/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 23428f0b0c0..5bbc10af25d 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 @@ -121,7 +122,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 +190,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 @@ -391,6 +385,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/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi index fa356d913e2..00a1b23a67b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi @@ -15,7 +15,6 @@ import logging _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) # This function will ascii encode unicode string inputs if neccesary. # In Python3, unicode strings are the default str type. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index f9d1e863ca9..ce701724fd3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -19,7 +19,6 @@ import time import grpc _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) cdef class Server: 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/_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/_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]) diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py index 53af2ff9135..916ee080b60 100644 --- a/src/python/grpcio/grpc/_plugin_wrapping.py +++ b/src/python/grpcio/grpc/_plugin_wrapping.py @@ -21,7 +21,6 @@ from grpc import _common from grpc._cython import cygrpc _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) class _AuthMetadataContext( 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/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py index 36066e19df5..24daf3406f8 100644 --- a/src/python/grpcio/grpc/framework/foundation/callable_util.py +++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py @@ -22,7 +22,6 @@ import logging import six _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) class Outcome(six.with_metaclass(abc.ABCMeta)): diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py index dfb8dbdc30a..216e3990db0 100644 --- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py +++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py @@ -18,7 +18,6 @@ import logging from concurrent import futures _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) def _wrap(behavior): diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py index e03130cced7..1faaf29bd7e 100644 --- a/src/python/grpcio/grpc/framework/foundation/stream_util.py +++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py @@ -20,7 +20,6 @@ from grpc.framework.foundation import stream _NO_VALUE = object() _LOGGER = logging.getLogger(__name__) -_LOGGER.addHandler(logging.NullHandler()) class TransformingConsumer(stream.Consumer): diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 42a4a7aa045..ce65c594fe2 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', @@ -323,18 +324,17 @@ CORE_SOURCE_FILES = [ '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/method_params.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', '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/retry_throttle.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', 'src/core/ext/filters/client_channel/health/health.pb.c', - 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', 'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc', 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_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..573b9d0d5ac --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -0,0 +1,141 @@ +# 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.""" + + @staticmethod + def GetTopChannels(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_top_channels(request.start_channel_id), + _channelz_pb2.GetTopChannelsResponse(), + ) + except (ValueError, json_format.ParseError) as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetServers(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_servers(request.start_server_id), + _channelz_pb2.GetServersResponse(), + ) + except (ValueError, json_format.ParseError) as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @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.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetServerSockets(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.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @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.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @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.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @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.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + +def add_channelz_servicer(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. + """ + _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_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/commands.py b/src/python/grpcio_tests/commands.py index d163f6fb68e..65e9a99950e 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -132,7 +132,12 @@ 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 = [] 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/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..84f85946896 --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -0,0 +1,494 @@ +# 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, 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) + 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): + self._pairs = [] + # 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.add_channelz_servicer(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() + _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) + + @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( + 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) + + @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 + 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) + + @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) + 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 + + @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) + + 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.NOT_FOUND', 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.NOT_FOUND', 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.NOT_FOUND', 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.NOT_FOUND', 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.NOT_FOUND', str(e)) + else: + self.fail('Invalid query not detected') + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index a39f30d32ab..aebdbf67ebf 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -35,6 +35,10 @@ py_library( requirement('google-auth'), requirement('requests'), requirement('enum34'), + requirement('urllib3'), + requirement('chardet'), + requirement('certifi'), + requirement('idna'), ], imports=["../../",], ) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 721dedf0b75..c11f6c8fad7 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 @@ -377,7 +376,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)) @@ -391,7 +390,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( @@ -422,7 +421,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 +434,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 +443,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( 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/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() diff --git a/src/python/grpcio_tests/tests/unit/_logging_test.py b/src/python/grpcio_tests/tests/unit/_logging_test.py index 80b1f1b3c12..631b9de9db5 100644 --- a/src/python/grpcio_tests/tests/unit/_logging_test.py +++ b/src/python/grpcio_tests/tests/unit/_logging_test.py @@ -68,6 +68,13 @@ class LoggingTest(unittest.TestCase): self.assertEqual(1, len(logging.getLogger().handlers)) self.assertIs(logging.getLogger().handlers[0].stream, intended_stream) + @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) + if __name__ == '__main__': unittest.main(verbosity=2) 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): 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=["../../../",], -) - - 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/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/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) 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/templates/Makefile.template b/templates/Makefile.template index 0b67416d3e7..8bb06176bf8 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -1370,7 +1370,7 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]})-dll.a $(prefix)/lib/lib${lib.name}.a else ifneq ($(SYSTEM),Darwin) - $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.core_version.major} + $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major} $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so endif % endif diff --git a/templates/config.m4.template b/templates/config.m4.template index 19f99049111..18378cfc34d 100644 --- a/templates/config.m4.template +++ b/templates/config.m4.template @@ -45,7 +45,8 @@ % endfor , $ext_shared, , -fvisibility=hidden ${"\\"} -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN ${"\\"} - -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0) + -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 ${"\\"} + -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1) PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) <% diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index ed69a1ed4ca..ab330415af2 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -132,7 +132,7 @@ s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '0.0.3' + version = '0.0.4' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' 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/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/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/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/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" 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/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 diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc index f85a2e46753..62a3ea4d53e 100644 --- a/test/core/gprpp/ref_counted_test.cc +++ b/test/core/gprpp/ref_counted_test.cc @@ -29,7 +29,10 @@ namespace { class Foo : public RefCounted { public: - Foo() {} + Foo() { + static_assert(std::has_virtual_destructor::value, + "PolymorphicRefCount doesn't have a virtual dtor"); + } }; TEST(RefCounted, Basic) { @@ -45,6 +48,28 @@ TEST(RefCounted, ExtraRef) { foo->Unref(); } +class FooNonPolymorphic + : public RefCounted { + public: + FooNonPolymorphic() { + static_assert(!std::has_virtual_destructor::value, + "NonPolymorphicRefCount has a virtual dtor"); + } +}; + +TEST(RefCountedNonPolymorphic, Basic) { + FooNonPolymorphic* foo = New(); + foo->Unref(); +} + +TEST(RefCountedNonPolymorphic, ExtraRef) { + FooNonPolymorphic* foo = New(); + RefCountedPtr foop = foo->Ref(); + foop.release(); + foo->Unref(); + foo->Unref(); +} + // Note: We use DebugOnlyTraceFlag instead of TraceFlag to ensure that // things build properly in both debug and non-debug cases. DebugOnlyTraceFlag foo_tracer(true, "foo"); @@ -66,6 +91,26 @@ TEST(RefCountedWithTracing, Basic) { foo->Unref(DEBUG_LOCATION, "original_ref"); } +class FooNonPolymorphicWithTracing + : public RefCountedWithTracing { + public: + FooNonPolymorphicWithTracing() : RefCountedWithTracing(&foo_tracer) {} +}; + +TEST(RefCountedNonPolymorphicWithTracing, Basic) { + FooNonPolymorphicWithTracing* foo = New(); + RefCountedPtr foop = + foo->Ref(DEBUG_LOCATION, "extra_ref"); + foop.release(); + foo->Unref(DEBUG_LOCATION, "extra_ref"); + // Can use the no-argument methods, too. + foop = foo->Ref(); + foop.release(); + foo->Unref(); + foo->Unref(DEBUG_LOCATION, "original_ref"); +} + } // namespace } // namespace testing } // namespace grpc_core 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/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index c7f30fa092c..e104e8e91a0 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..33437373e4e 100644 --- a/test/core/transport/chttp2/BUILD +++ b/test/core/transport/chttp2/BUILD @@ -66,6 +66,22 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "context_list_test", + srcs = ["context_list_test.cc"], + external_deps = [ + "gtest", + ], + 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..e64f1532ecd --- /dev/null +++ b/test/core/transport/chttp2/context_list_test.cc @@ -0,0 +1,102 @@ +/* + * + * 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 +#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 + +namespace grpc_core { +namespace testing { +namespace { + +const uint32_t kByteOffset = 123; + +void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { + ASSERT_NE(arg, nullptr); + EXPECT_EQ(ts->byte_offset, kByteOffset); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +void discard_write(grpc_slice slice) {} + +/** Tests that all ContextList elements in the list are flushed out on + * execute. + * Also tests that arg and byte_counter are passed correctly. + */ +TEST(ContextList, ExecuteFlushesList) { + grpc_core::ContextList* list = nullptr; + grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); + 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 = + grpc_mock_endpoint_create(discard_write, resource_quota); + grpc_transport* t = + grpc_create_chttp2_transport(nullptr, mock_endpoint, true); + std::vector s; + 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), + 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++) { + EXPECT_EQ(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(); +} +} // namespace +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index ef6fd62b516..e5867cd526b 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -103,18 +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, -}; +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 3cc8ad6fe14..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,6 +173,7 @@ static const grpc_endpoint_vtable vtable = { me_get_resource_user, me_get_peer, me_get_fd, + 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 62ed72a6295..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); @@ -148,7 +150,8 @@ static const grpc_endpoint_vtable vtable = {te_read, te_destroy, te_get_resource_user, te_get_peer, - te_get_fd}; + te_get_fd, + te_can_track_err}; grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap, double bytes_per_second) { diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 7ffc610ce2b..a35991396ad 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -34,6 +34,7 @@ #include "test/core/util/test_config.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 @@ -100,11 +101,13 @@ class ClientCallbackEnd2endTest test_string += "Hello world. "; request.set_message(test_string); - + grpc::string val; if (with_binary_metadata) { + request.mutable_param()->set_echo_metadata(true); char bytes[8] = {'\0', '\1', '\2', '\3', '\4', '\5', '\6', static_cast(i)}; - cli_ctx.AddMetadata("custom-bin", grpc::string(bytes, 8)); + val = grpc::string(bytes, 8); + cli_ctx.AddMetadata("custom-bin", val); } cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); @@ -114,10 +117,18 @@ class ClientCallbackEnd2endTest bool done = false; stub_->experimental_async()->Echo( &cli_ctx, &request, &response, - [&request, &response, &done, &mu, &cv](Status s) { + [&cli_ctx, &request, &response, &done, &mu, &cv, val, + with_binary_metadata](Status s) { GPR_ASSERT(s.ok()); EXPECT_EQ(request.message(), response.message()); + if (with_binary_metadata) { + EXPECT_EQ( + 1u, cli_ctx.GetServerTrailingMetadata().count("custom-bin")); + EXPECT_EQ(val, ToString(cli_ctx.GetServerTrailingMetadata() + .find("custom-bin") + ->second)); + } std::lock_guard l(mu); done = true; cv.notify_one(); diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 0b34ec93ae7..60e8b051ab8 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -361,15 +361,13 @@ class ClientInterceptorsEnd2endTest : public ::testing::Test { TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back(std::unique_ptr( + std::vector> + creators; + creators.push_back(std::unique_ptr( new LoggingInterceptorFactory())); // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -382,20 +380,18 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) { TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); + std::vector> + creators; // Add 20 dummy interceptors before hijacking interceptor for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new HijackingInterceptorFactory())); // Add 20 dummy interceptors after hijacking interceptor for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -408,13 +404,11 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLogThenHijackTest) { ChannelArguments args; - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back(std::unique_ptr( + std::vector> + creators; + creators.push_back(std::unique_ptr( new LoggingInterceptorFactory())); - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new HijackingInterceptorFactory())); auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); @@ -426,21 +420,19 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingMakesAnotherCallTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); + std::vector> + creators; // Add 5 dummy interceptors before hijacking interceptor for (auto i = 0; i < 5; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } - creators->push_back( + creators.push_back( std::unique_ptr( new HijackingInterceptorMakesAnotherCallFactory())); // Add 7 dummy interceptors after hijacking interceptor for (auto i = 0; i < 7; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = server_->experimental().InProcessChannelWithInterceptors( @@ -456,15 +448,13 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTestWithCallback) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back(std::unique_ptr( + std::vector> + creators; + creators.push_back(std::unique_ptr( new LoggingInterceptorFactory())); // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = server_->experimental().InProcessChannelWithInterceptors( @@ -496,15 +486,13 @@ class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test { TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back(std::unique_ptr( + std::vector> + creators; + creators.push_back(std::unique_ptr( new LoggingInterceptorFactory())); // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -517,15 +505,13 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) { TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back(std::unique_ptr( + std::vector> + creators; + creators.push_back(std::unique_ptr( new LoggingInterceptorFactory())); // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -538,15 +524,13 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back(std::unique_ptr( + std::vector> + creators; + creators.push_back(std::unique_ptr( new LoggingInterceptorFactory())); // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -583,13 +567,11 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) { experimental::RegisterGlobalClientInterceptorFactory(&global_factory); ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); + std::vector> + creators; // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -610,13 +592,11 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { experimental::RegisterGlobalClientInterceptorFactory(&global_factory); ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); + std::vector> + creators; // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( @@ -637,13 +617,11 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { experimental::RegisterGlobalClientInterceptorFactory(&global_factory); ChannelArguments args; DummyInterceptor::Reset(); - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); + std::vector> + creators; // Add 20 dummy interceptors for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } auto channel = experimental::CreateCustomChannelWithInterceptors( diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 9218c85717b..312065a2dfe 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -149,7 +149,7 @@ class ClientLbEnd2endTest : public ::testing::Test { void StartServers(size_t num_servers, std::vector ports = std::vector()) { - CreateServers(num_servers, ports); + CreateServers(num_servers, std::move(ports)); for (size_t i = 0; i < num_servers; ++i) { StartServer(i); } @@ -191,6 +191,11 @@ class ClientLbEnd2endTest : public ::testing::Test { grpc_channel_args_destroy(fake_results); } + void SetFailureOnReresolution() { + grpc_core::ExecCtx exec_ctx; + response_generator_->SetFailureOnReresolution(); + } + std::vector GetServersPorts() { std::vector ports; for (const auto& server : servers_) ports.push_back(server->port_); @@ -728,6 +733,23 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) { + // 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. + SetFailureOnReresolution(); + servers_[0]->Shutdown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); + servers_.clear(); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 4558437102d..03291e1785c 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -272,6 +272,7 @@ class End2endTest : public ::testing::TestWithParam { 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())); 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); diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc index 602d1695a3a..5d59c1a4b72 100644 --- a/test/cpp/end2end/interceptors_util.cc +++ b/test/cpp/end2end/interceptors_util.cc @@ -132,16 +132,13 @@ bool CheckMetadata(const std::multimap& map, return false; } -std::unique_ptr>> +std::vector> CreateDummyClientInterceptors() { - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); + std::vector> + creators; // Add 20 dummy interceptors before hijacking interceptor for (auto i = 0; i < 20; i++) { - creators->push_back(std::unique_ptr( + creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); } return creators; diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index b4c4791fcaa..d886e32494c 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -149,8 +149,7 @@ void MakeCallbackCall(const std::shared_ptr& channel); bool CheckMetadata(const std::multimap& map, const string& key, const string& value); -std::unique_ptr>> +std::vector> CreateDummyClientInterceptors(); inline void* tag(int i) { return (void*)static_cast(i); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 4ae086ea76d..295d63516bd 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -391,6 +391,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { builder.RegisterAsyncGenericService(&service); std::vector> creators; + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -486,6 +487,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnimplementedRpcTest) { builder.AddListeningPort(server_address, InsecureServerCredentials()); std::vector> creators; + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -539,6 +541,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) { builder.AddListeningPort(server_address, InsecureServerCredentials()); std::vector> creators; + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index a99cf8122f8..4ff153f980a 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -76,7 +76,7 @@ void UnaryCompressionChecks(const InteropClientContextInspector& inspector, InteropClient::ServiceStub::ServiceStub( ChannelCreationFunc channel_creation_func, bool new_stub_every_call) - : channel_creation_func_(channel_creation_func), + : channel_creation_func_(std::move(channel_creation_func)), channel_(channel_creation_func_()), new_stub_every_call_(new_stub_every_call) { // If new_stub_every_call is false, then this is our chance to initialize @@ -112,7 +112,7 @@ void InteropClient::ServiceStub::ResetChannel() { InteropClient::InteropClient(ChannelCreationFunc channel_creation_func, bool new_stub_every_test_case, bool do_not_abort_on_transient_failures) - : serviceStub_(channel_creation_func, new_stub_every_test_case), + : serviceStub_(std::move(channel_creation_func), new_stub_every_test_case), do_not_abort_on_transient_failures_(do_not_abort_on_transient_failures) {} bool InteropClient::AssertStatusOk(const Status& s, diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc index 7dc1956f783..5bbe913365c 100644 --- a/test/cpp/interop/stress_interop_client.cc +++ b/test/cpp/interop/stress_interop_client.cc @@ -73,7 +73,7 @@ StressTestInteropClient::StressTestInteropClient( long sleep_duration_ms, bool do_not_abort_on_transient_failures) : test_id_(test_id), server_address_(server_address), - channel_creation_func_(channel_creation_func), + channel_creation_func_(std::move(channel_creation_func)), interop_client_(new InteropClient(channel_creation_func_, false, do_not_abort_on_transient_failures)), test_selector_(test_selector), diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 446dc93edb9..8d12606434b 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -135,7 +135,8 @@ static void BM_LameChannelCallCreateCpp(benchmark::State& state) { "", grpc_lame_client_channel_create("localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"), - nullptr)); + std::vector>())); grpc::CompletionQueue cq; grpc::testing::EchoRequest send_request; grpc::testing::EchoResponse recv_response; 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/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; diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index e57eb6ddd11..71e8d9972bf 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -218,7 +218,10 @@ 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, nullptr); + 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 32eab1fc444..baeede34ea4 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -118,7 +118,10 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = CreateChannelInternal("", channel, nullptr); + channel_ = CreateChannelInternal( + "", channel, + std::vector>()); } } 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/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..1d67e79b868 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.empty()) { + 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); diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index c8d4333ef0d..57eaf3baf2f 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -185,6 +185,7 @@ grpc_cc_test( external_deps = [ "gtest", ], + tags = ["nomsan"], # death tests seem to be incompatible with msan deps = [ ":grpc_cli_libs", ":test_util", diff --git a/third_party/data-plane-api b/third_party/data-plane-api new file mode 160000 index 00000000000..911001cdca0 --- /dev/null +++ b/third_party/data-plane-api @@ -0,0 +1 @@ +Subproject commit 911001cdca003337bdb93fab32740cde61bafee3 diff --git a/third_party/googleapis b/third_party/googleapis new file mode 160000 index 00000000000..80ed4d0bbf6 --- /dev/null +++ b/third_party/googleapis @@ -0,0 +1 @@ +Subproject commit 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b diff --git a/third_party/protoc-gen-validate b/third_party/protoc-gen-validate new file mode 160000 index 00000000000..e143189bf6f --- /dev/null +++ b/third_party/protoc-gen-validate @@ -0,0 +1 @@ +Subproject commit e143189bf6f37b3957fb31743df6a1bcf4a8c685 diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 02cd87a7b9b..e213461acc9 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -16,37 +16,72 @@ 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_r342117", +) + +alias( + name = "rbe_ubuntu1604_large", + actual = ":rbe_ubuntu1604_r342117_large", ) -# RBE Ubuntu16_04 r328903 +# RBE Ubuntu16_04 r342117 platform( - name = "rbe_ubuntu1604_r328903", + name = "rbe_ubuntu1604_r342117", 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:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375" } properties: { name: "gceMachineType" # Small machines for majority of tests. value: "n1-highmem-2" } + """, +) + +# RBE Ubuntu16_04 r342117 large +platform( + name = "rbe_ubuntu1604_r342117_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: "container-image" + value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375" + } properties: { - name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN. + name: "gceMachineType" # Large machines for some resource demanding tests (TSAN). value: "n1-standard-8" } - """, + """, +) + +# 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_type = "@bazel_tools//tools/cpp:toolchain_type", ) 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/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/bazel.rc b/tools/bazel.rc index d33e6e086b0..59e597b4723 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -6,13 +6,17 @@ build --client_env=CC=clang build --copt=-DGRPC_BAZEL_BUILD +build:opt --compilation_mode=opt build:opt --copt=-Wframe-larger-than=16384 +build:dbg --compilation_mode=dbg + build:asan --strip=never build:asan --copt=-fsanitize=address build:asan --copt=-O0 build:asan --copt=-fno-omit-frame-pointer build:asan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:asan --copt=-DADDRESS_SANITIZER # used by absl build:asan --linkopt=-fsanitize=address build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1 @@ -24,6 +28,7 @@ build:msan --copt=-fsanitize-memory-track-origins build:msan --copt=-fsanitize-memory-use-after-dtor build:msan --copt=-fno-omit-frame-pointer build:msan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:msan --copt=-DMEMORY_SANITIZER # used by absl build:msan --linkopt=-fsanitize=memory build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1 @@ -32,6 +37,8 @@ build:tsan --copt=-fsanitize=thread build:tsan --copt=-fno-omit-frame-pointer build:tsan --copt=-DGPR_NO_DIRECT_SYSCALLS build:tsan --copt=-DGRPC_TSAN +# TODO(jtattermusch): ideally we would set --copt=-DTHREAD_SANITIZER (used by absl) +# but it seems to do more harm than good and triggers #17175 build:tsan --linkopt=-fsanitize=thread build:tsan --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 @@ -40,6 +47,7 @@ build:ubsan --copt=-fsanitize=undefined build:ubsan --copt=-fno-omit-frame-pointer build:ubsan --copt=-DGRPC_UBSAN build:ubsan --copt=-DNDEBUG +build:ubsan --copt=-DUNDEFINED_BEHAVIOR_SANITIZER # used by absl build:ubsan --copt=-fno-sanitize=function,vptr build:ubsan --linkopt=-fsanitize=undefined build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1:suppressions=test/core/util/ubsan_suppressions.txt 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', 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/distrib/python/docgen.py b/tools/distrib/python/docgen.py index 732d948bbca..de47c00618d 100755 --- a/tools/distrib/python/docgen.py +++ b/tools/distrib/python/docgen.py @@ -32,12 +32,10 @@ parser.add_argument( help='GRPC/GPR libraries build configuration', default='opt') parser.add_argument('--submit', action='store_true') -parser.add_argument('--gh-user', type=str, help='GitHub user to push as.') parser.add_argument( - '--gh-repo-owner', + '--repo-owner', type=str, - help=('Owner of the GitHub repository to be pushed; ' - 'defaults to --gh-user.')) + help=('Owner of the GitHub repository to be pushed')) parser.add_argument('--doc-branch', type=str) args = parser.parse_args() @@ -70,7 +68,7 @@ subprocess_arguments_list = [ 'env': environment }, { - 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==10.0.1'], + 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==18.1'], 'env': environment }, { @@ -78,7 +76,7 @@ subprocess_arguments_list = [ 'env': environment }, { - 'args': [VIRTUALENV_PYTHON_PATH, SETUP_PATH, 'build'], + 'args': [VIRTUALENV_PIP_PATH, 'install', 'Sphinx~=1.8.1'], 'env': environment }, { @@ -91,12 +89,12 @@ for subprocess_arguments in subprocess_arguments_list: print('Running command: {}'.format(subprocess_arguments['args'])) subprocess.check_call(**subprocess_arguments) -if args.submit: - assert args.gh_user +if not args.submit: + print('Please check generated Python doc inside doc/build') +elif args.submit: + assert args.repo_owner assert args.doc_branch - github_user = args.gh_user - github_repository_owner = (args.gh_repo_owner - if args.gh_repo_owner else args.gh_user) + github_repository_owner = args.repo_owner # Create a temporary directory out of tree, checkout gh-pages from the # specified repository, edit it, and push it. It's up to the user to then go # onto GitHub and make a PR against grpc/grpc:gh-pages. @@ -109,16 +107,19 @@ if args.submit: print('Cloning your repository...') subprocess.check_call( [ - 'git', 'clone', 'https://{}@github.com/{}/grpc'.format( - github_user, github_repository_owner) + 'git', + 'clone', + '--branch', + 'gh-pages', + 'https://github.com/grpc/grpc', ], cwd=repo_parent_dir) + subprocess.check_call(['git', 'checkout', '-b', doc_branch], cwd=repo_dir) subprocess.check_call( - ['git', 'remote', 'add', 'upstream', 'https://github.com/grpc/grpc'], - cwd=repo_dir) - subprocess.check_call(['git', 'fetch', 'upstream'], cwd=repo_dir) - subprocess.check_call( - ['git', 'checkout', 'upstream/gh-pages', '-b', doc_branch], + [ + 'git', 'remote', 'add', 'ssh-origin', + 'git@github.com:%s/grpc.git' % (github_repository_owner) + ], cwd=repo_dir) print('Updating documentation...') shutil.rmtree(python_doc_dir, ignore_errors=True) @@ -130,7 +131,7 @@ if args.submit: ['git', 'commit', '-m', 'Auto-update Python documentation'], cwd=repo_dir) subprocess.check_call( - ['git', 'push', '--set-upstream', 'origin', doc_branch], + ['git', 'push', '--set-upstream', 'ssh-origin', doc_branch], cwd=repo_dir) except subprocess.CalledProcessError: print('Failed to push documentation. Examine this directory and push ' 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/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 - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip +# 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 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 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 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 diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh index 7917e1cd60d..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 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.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/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/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/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 diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 392113c2843..5c19711ee91 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 @@ -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 a96683883ca..72b247c48da 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 @@ -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 791318bf363..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 \ @@ -926,8 +927,6 @@ 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 \ -src/core/ext/filters/client_channel/method_params.cc \ -src/core/ext/filters/client_channel/method_params.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 \ @@ -956,6 +955,8 @@ 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/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -1009,6 +1010,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 \ @@ -1527,8 +1530,6 @@ 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/alts_transport_security.cc \ -src/core/tsi/alts_transport_security.h \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/fake_transport_security.h \ src/core/tsi/grpc_shadow_boringssl.h \ diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 2362b370d54..f5b0b764b14 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -15,14 +15,8 @@ # Source this rc script to prepare the environment for macos builds -sudo launchctl limit maxfiles unlimited unlimited - -# show current maxfiles +# show original open file limit values launchctl limit maxfiles - -ulimit -n 10000 - -# show current limits ulimit -a # synchronize the clock @@ -97,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 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 d3cd9c20ccc..fdd5b2e4cde 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="-c dbg --test_timeout=300,450,1200,3600 --cache_test_results=no" +EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600 --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 48b3f9e6743..30b2b17a674 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="-c opt --test_timeout=300,450,1200,3600 --cache_test_results=no" +EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600 --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_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh index 97166372ab4..a91cffdf989 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 2 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l python -x coverage_python/sponge_log.xml \ + --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 2 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l php -x coverage_php/sponge_log.xml \ + --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. 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 4f98d0a93a7..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 @@ -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/test -bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... 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 eb1c7320a71..f1e6588517e 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="-c dbg --test_timeout=300,450,1200,3600" +EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600" 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 f179dc9483a..77744de49fa 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="-c opt --test_timeout=300,450,1200,3600" +EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/run_tests/helper_scripts/run_lcov.sh b/tools/internal_ci/linux/pull_request/grpc_msan_on_foundry.sh old mode 100755 new mode 100644 similarity index 58% rename from tools/run_tests/helper_scripts/run_lcov.sh rename to tools/internal_ci/linux/pull_request/grpc_msan_on_foundry.sh index 9d8b6793fce..c85a837a440 --- a/tools/run_tests/helper_scripts/run_lcov.sh +++ b/tools/internal_ci/linux/pull_request/grpc_msan_on_foundry.sh @@ -1,5 +1,5 @@ -#!/bin/bash -# Copyright 2015 gRPC authors. +#!/usr/bin/env 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. @@ -15,17 +15,4 @@ 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 +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=msan diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md index c4d03547a21..19739e9ee12 100644 --- a/tools/remote_build/README.md +++ b/tools/remote_build/README.md @@ -17,10 +17,10 @@ and tests run by Kokoro CI. ## Running remote build manually from dev workstation -Run from repository root: +Run from repository root (opt, dbg): ``` # manual run of bazel tests remotely on Foundry -bazel --bazelrc=tools/remote_build/manual.bazelrc test -c opt //test/... +bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=opt //test/... ``` Sanitizer runs (asan, msan, tsan, ubsan): diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index e8c7f0b9cb6..aa3ddb050cd 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -18,10 +18,10 @@ 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=//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 +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 @@ -48,27 +48,30 @@ test --test_env=GRPC_VERBOSITY=debug build:asan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:asan --test_timeout=3600 -build:asan --test_tag_filters=-qps_json_driver,-json_run_localhost +build:asan --test_tag_filters=-qps_json_driver # memory sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific build:msan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:msan --test_timeout=3600 +# TODO(jtattermusch): revisit the disabled tests +build:msan --test_tag_filters=-nomsan,-json_run_localhost 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 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 --test_tag_filters=-qps_json_driver +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 @@ -76,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.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. diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py index d18ea2aca1e..aa1d0c3bf22 100644 --- a/tools/run_tests/artifacts/artifact_targets.py +++ b/tools/run_tests/artifacts/artifact_targets.py @@ -124,6 +124,8 @@ class PythonArtifact: # https://github.com/resin-io-projects/armv7hf-debian-qemu/issues/9 # A QEMU bug causes submodule update to hang, so we copy directly environ['RELATIVE_COPY_PATH'] = '.' + # Parallel builds are counterproductive in emulated environment + environ['GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS'] = '1' extra_args = ' --entrypoint=/usr/bin/qemu-arm-static ' return create_docker_jobspec( self.name, diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 9a2e0f739f3..bc6e5582046 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -24,7 +24,8 @@ export AUDITWHEEL=${AUDITWHEEL:-auditwheel} # Allow build_ext to build C/C++ files in parallel # by enabling a monkeypatch. It speeds up the build a lot. -export GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS=2 +# Use externally provided GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS value if set. +export GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS=${GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS:-2} mkdir -p "${ARTIFACTS_OUT}" ARTIFACT_DIR="$PWD/${ARTIFACTS_OUT}" @@ -107,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/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" \ 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 diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 47bc525f0d0..4d9bbb0f09e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3507,6 +3507,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "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", @@ -10035,13 +10052,13 @@ "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/method_params.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", "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/retry_throttle.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_index.h" @@ -10074,8 +10091,6 @@ "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/method_params.cc", - "src/core/ext/filters/client_channel/method_params.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", @@ -10087,6 +10102,8 @@ "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/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/subchannel.cc", @@ -10736,6 +10753,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", @@ -10765,6 +10783,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", @@ -11111,7 +11131,6 @@ "tsi_interface" ], "headers": [ - "src/core/tsi/alts_transport_security.h", "src/core/tsi/fake_transport_security.h", "src/core/tsi/local_transport_security.h", "src/core/tsi/ssl/session_cache/ssl_session.h", @@ -11124,8 +11143,6 @@ "language": "c", "name": "tsi", "src": [ - "src/core/tsi/alts_transport_security.cc", - "src/core/tsi/alts_transport_security.h", "src/core/tsi/fake_transport_security.cc", "src/core/tsi/fake_transport_security.h", "src/core/tsi/local_transport_security.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index ef34cd65562..cc28e52ae21 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3990,7 +3990,7 @@ "posix", "windows" ], - "cpu_cost": 1.0, + "cpu_cost": 10.0, "exclude_configs": [], "exclude_iomgrs": [], "flaky": false, @@ -4123,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": true, + "language": "c++", + "name": "context_list_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh index 4c94c4c6d22..e43f1fb429c 100755 --- a/tools/run_tests/helper_scripts/build_python.sh +++ b/tools/run_tests/helper_scripts/build_python.sh @@ -56,6 +56,12 @@ function is_linux() { fi } +function inside_venv() { + if [[ -n "${VIRTUAL_ENV}" ]]; then + echo true + fi +} + # Associated virtual environment name for the given python command. function venv() { $1 -c "import sys; print('py{}{}'.format(*sys.version_info[:2]))" @@ -134,10 +140,14 @@ fi # Perform build operations # ############################ -# Instantiate the virtualenv from the Python version passed in. -$PYTHON -m pip install --user virtualenv -$PYTHON -m virtualenv "$VENV" -VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON") +if [[ "$(inside_venv)" ]]; then + VENV_PYTHON="$PYTHON" +else + # Instantiate the virtualenv from the Python version passed in. + $PYTHON -m pip install --user virtualenv + $PYTHON -m virtualenv "$VENV" + VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON") +fi # See https://github.com/grpc/grpc/issues/14815 for more context. We cannot rely # on pip to upgrade itself because if pip is too old, it may not have the required @@ -179,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 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" + # 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 diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index ff6682c3cf8..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 [ - 'py27_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 [ - 'py27_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 [ - 'py27_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)) ] diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a1f2aaab2f3..f71be2a65e9 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: @@ -1340,9 +1342,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 +1515,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 +1527,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([ 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 8ea53dfec5c..f1103596d51 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -32,11 +32,15 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" 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) + 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) 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 diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 2a5dcda5be5..549ae14f5ab 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -39,6 +39,7 @@ BANNED_EXCEPT = { 'grpc_wsa_error(': ['src/core/lib/iomgr/error.cc'], 'grpc_log_if_error(': ['src/core/lib/iomgr/error.cc'], 'grpc_slice_malloc(': ['src/core/lib/slice/slice.cc'], + 'grpc_call_cancel_internal(': ['src/core/lib/surface/call.cc'], 'grpc_closure_create(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_init(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_sched(': ['src/core/lib/iomgr/closure.cc'],