diff --git a/BUILD b/BUILD index 8523bbb660f..ee4b5dfaecc 100644 --- a/BUILD +++ b/BUILD @@ -64,11 +64,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "gladiolus" +g_stands_for = "glider" core_version = "6.0.0-dev" -version = "1.14.0-dev" +version = "1.15.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", @@ -2053,6 +2053,26 @@ grpc_cc_library( alwayslink = 1, ) +grpc_cc_library( + name = "grpcpp_channelz", + srcs = [ + "src/cpp/server/channelz/channelz_service.cc", + "src/cpp/server/channelz/channelz_service_plugin.cc", + ], + hdrs = [ + "src/cpp/server/channelz/channelz_service.h", + ], + language = "c++", + public_hdrs = [ + "include/grpcpp/ext/channelz_service_plugin.h", + ], + deps = [ + ":grpc++", + "//src/proto/grpc/channelz:channelz_proto", + ], + alwayslink = 1, +) + grpc_cc_library( name = "grpc++_test", public_hdrs = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 7222894af62..84e9c08cb5b 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.14.0-dev") +set(PACKAGE_VERSION "1.15.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/") @@ -551,6 +551,7 @@ add_dependencies(buildtests_cxx channel_arguments_test) add_dependencies(buildtests_cxx channel_filter_test) add_dependencies(buildtests_cxx channel_trace_test) add_dependencies(buildtests_cxx channelz_registry_test) +add_dependencies(buildtests_cxx channelz_service_test) add_dependencies(buildtests_cxx channelz_test) add_dependencies(buildtests_cxx check_gcp_environment_linux_test) add_dependencies(buildtests_cxx check_gcp_environment_windows_test) @@ -4690,6 +4691,73 @@ if (gRPC_INSTALL) ) endif() + +if (gRPC_BUILD_CODEGEN) +add_library(grpcpp_channelz + src/cpp/server/channelz/channelz_service.cc + src/cpp/server/channelz/channelz_service_plugin.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h +) + +if(WIN32 AND MSVC) + set_target_properties(grpcpp_channelz PROPERTIES COMPILE_PDB_NAME "grpcpp_channelz" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpcpp_channelz.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +protobuf_generate_grpc_cpp( + src/proto/grpc/channelz/channelz.proto +) + +target_include_directories(grpcpp_channelz + PUBLIC $ $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpcpp_channelz + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc +) + +foreach(_hdr + include/grpcpp/ext/channelz_service_plugin.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() +endif (gRPC_BUILD_CODEGEN) + + +if (gRPC_INSTALL) + install(TARGETS grpcpp_channelz EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + if (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -5096,6 +5164,7 @@ add_library(qps test/cpp/qps/client_sync.cc test/cpp/qps/driver.cc test/cpp/qps/parse_json.cc + test/cpp/qps/qps_server_builder.cc test/cpp/qps/qps_worker.cc test/cpp/qps/report.cc test/cpp/qps/server_async.cc @@ -10873,6 +10942,54 @@ target_link_libraries(channelz_registry_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(channelz_service_test + test/cpp/end2end/channelz_service_test.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +protobuf_generate_grpc_cpp( + src/proto/grpc/channelz/channelz.proto +) + +target_include_directories(channelz_service_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(channelz_service_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpcpp_channelz + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(channelz_test test/core/channel/channelz_test.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc diff --git a/Makefile b/Makefile index 47c9dc7ccdf..bad41975a05 100644 --- a/Makefile +++ b/Makefile @@ -437,8 +437,8 @@ Q = @ endif CORE_VERSION = 6.0.0-dev -CPP_VERSION = 1.14.0-dev -CSHARP_VERSION = 1.14.0-dev +CPP_VERSION = 1.15.0-dev +CSHARP_VERSION = 1.15.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) @@ -1142,6 +1142,7 @@ channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test channel_trace_test: $(BINDIR)/$(CONFIG)/channel_trace_test channelz_registry_test: $(BINDIR)/$(CONFIG)/channelz_registry_test +channelz_service_test: $(BINDIR)/$(CONFIG)/channelz_service_test channelz_test: $(BINDIR)/$(CONFIG)/channelz_test check_gcp_environment_linux_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test check_gcp_environment_windows_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test @@ -1378,12 +1379,14 @@ static: static_c static_cxx static_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a -static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a +static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a + +static_csharp: static_c $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a shared: shared_c shared_cxx shared_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) +shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) grpc_csharp_ext: shared_csharp @@ -1640,6 +1643,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/channel_filter_test \ $(BINDIR)/$(CONFIG)/channel_trace_test \ $(BINDIR)/$(CONFIG)/channelz_registry_test \ + $(BINDIR)/$(CONFIG)/channelz_service_test \ $(BINDIR)/$(CONFIG)/channelz_test \ $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test \ $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \ @@ -1818,6 +1822,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/channel_filter_test \ $(BINDIR)/$(CONFIG)/channel_trace_test \ $(BINDIR)/$(CONFIG)/channelz_registry_test \ + $(BINDIR)/$(CONFIG)/channelz_service_test \ $(BINDIR)/$(CONFIG)/channelz_test \ $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test \ $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \ @@ -2261,6 +2266,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/channel_trace_test || ( echo test channel_trace_test failed ; exit 1 ) $(E) "[RUN] Testing channelz_registry_test" $(Q) $(BINDIR)/$(CONFIG)/channelz_registry_test || ( echo test channelz_registry_test failed ; exit 1 ) + $(E) "[RUN] Testing channelz_service_test" + $(Q) $(BINDIR)/$(CONFIG)/channelz_service_test || ( echo test channelz_service_test failed ; exit 1 ) $(E) "[RUN] Testing channelz_test" $(Q) $(BINDIR)/$(CONFIG)/channelz_test || ( echo test channelz_test failed ; exit 1 ) $(E) "[RUN] Testing check_gcp_environment_linux_test" @@ -2459,6 +2466,8 @@ ifeq ($(CONFIG),opt) $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(E) "[STRIP] Stripping libgrpc++_unsecure.a" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a + $(E) "[STRIP] Stripping libgrpcpp_channelz.a" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a endif strip-shared_c: shared_c @@ -2487,6 +2496,8 @@ ifeq ($(CONFIG),opt) $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) + $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) endif strip-shared_csharp: shared_csharp @@ -2946,6 +2957,9 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx $(E) "[INSTALL] Installing libgrpc++_unsecure.a" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a + $(E) "[INSTALL] Installing libgrpcpp_channelz.a" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(prefix)/lib/libgrpcpp_channelz.a @@ -3047,6 +3061,15 @@ ifeq ($(SYSTEM),MINGW32) else ifneq ($(SYSTEM),Darwin) $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.6 $(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)" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) +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.6 + $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so endif ifneq ($(SYSTEM),MINGW32) ifneq ($(SYSTEM),Darwin) @@ -7021,6 +7044,79 @@ ifneq ($(NO_DEPS),true) endif +LIBGRPCPP_CHANNELZ_SRC = \ + src/cpp/server/channelz/channelz_service.cc \ + src/cpp/server/channelz/channelz_service_plugin.cc \ + $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \ + +PUBLIC_HEADERS_CXX += \ + include/grpcpp/ext/channelz_service_plugin.h \ + +LIBGRPCPP_CHANNELZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPCPP_CHANNELZ_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: openssl_dep_error + +$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: protobuf_dep_error + +$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error + +else + +$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBGRPCPP_CHANNELZ_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBGRPCPP_CHANNELZ_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a +endif + + + +ifeq ($(SYSTEM),MINGW32) +$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll +else +$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` +ifeq ($(SYSTEM),Darwin) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc +else + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpcpp_channelz.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc + $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so.1 + $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so +endif +endif + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPCPP_CHANNELZ_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/src/cpp/server/channelz/channelz_service.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/src/cpp/server/channelz/channelz_service_plugin.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc + + LIBHTTP2_CLIENT_MAIN_SRC = \ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \ @@ -7344,6 +7440,7 @@ LIBQPS_SRC = \ test/cpp/qps/client_sync.cc \ test/cpp/qps/driver.cc \ test/cpp/qps/parse_json.cc \ + test/cpp/qps/qps_server_builder.cc \ test/cpp/qps/qps_worker.cc \ test/cpp/qps/report.cc \ test/cpp/qps/server_async.cc \ @@ -7399,6 +7496,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testin $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 $(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 $(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_server_builder.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 $(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 $(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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 @@ -16562,6 +16660,53 @@ endif endif +CHANNELZ_SERVICE_TEST_SRC = \ + test/cpp/end2end/channelz_service_test.cc \ + $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \ + +CHANNELZ_SERVICE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CHANNELZ_SERVICE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/channelz_service_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)/channelz_service_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_service_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_channelz_service_test: $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc + + CHANNELZ_TEST_SRC = \ test/core/channel/channelz_test.cc \ $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \ @@ -24517,6 +24662,8 @@ src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP) src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP) src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP) src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP) +src/cpp/server/channelz/channelz_service.cc: $(OPENSSL_DEP) +src/cpp/server/channelz/channelz_service_plugin.cc: $(OPENSSL_DEP) src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP) src/cpp/util/core_stats.cc: $(OPENSSL_DEP) src/cpp/util/error_details.cc: $(OPENSSL_DEP) @@ -24548,6 +24695,7 @@ test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_sync.cc: $(OPENSSL_DEP) test/cpp/qps/driver.cc: $(OPENSSL_DEP) test/cpp/qps/parse_json.cc: $(OPENSSL_DEP) +test/cpp/qps/qps_server_builder.cc: $(OPENSSL_DEP) test/cpp/qps/qps_worker.cc: $(OPENSSL_DEP) test/cpp/qps/report.cc: $(OPENSSL_DEP) test/cpp/qps/server_async.cc: $(OPENSSL_DEP) diff --git a/README.md b/README.md index 1af9ec34f0a..1960f44137c 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ For instructions on how to use the language-specific gRPC runtime in your projec 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. +Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are uploaded daily to [packages.grpc.io](https://packages.grpc.io). + # To start developing gRPC Contributions are welcome! diff --git a/build.yaml b/build.yaml index 3067ca9161d..30389ec1146 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: 6.0.0-dev - g_stands_for: gladiolus - version: 1.14.0-dev + g_stands_for: glider + version: 1.15.0-dev filegroups: - name: alts_proto headers: @@ -1111,10 +1111,6 @@ filegroups: secure: true uses: - grpc_trace -- name: grpc++_channelz_proto - language: c++ - src: - - src/proto/grpc/channelz/channelz.proto - name: grpc++_codegen_base language: c++ public_headers: @@ -1359,6 +1355,10 @@ filegroups: deps: - grpc++ - grpc +- name: grpcpp_channelz_proto + language: c++ + src: + - src/proto/grpc/channelz/channelz.proto libs: - name: address_sorting build: all @@ -1851,6 +1851,21 @@ libs: vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}' vs_props: - protoc +- name: grpcpp_channelz + build: all + language: c++ + public_headers: + - include/grpcpp/ext/channelz_service_plugin.h + headers: + - src/cpp/server/channelz/channelz_service.h + src: + - src/cpp/server/channelz/channelz_service.cc + - src/cpp/server/channelz/channelz_service_plugin.cc + deps: + - grpc++ + - grpc + filegroups: + - grpcpp_channelz_proto - name: http2_client_main build: private language: c++ @@ -1948,6 +1963,7 @@ libs: - test/cpp/qps/histogram.h - test/cpp/qps/interarrival.h - test/cpp/qps/parse_json.h + - test/cpp/qps/qps_server_builder.h - test/cpp/qps/qps_worker.h - test/cpp/qps/report.h - test/cpp/qps/server.h @@ -1966,6 +1982,7 @@ libs: - test/cpp/qps/client_sync.cc - test/cpp/qps/driver.cc - test/cpp/qps/parse_json.cc + - test/cpp/qps/qps_server_builder.cc - test/cpp/qps/qps_worker.cc - test/cpp/qps/report.cc - test/cpp/qps/server_async.cc @@ -4295,7 +4312,7 @@ targets: - gpr_test_util - gpr filegroups: - - grpc++_channelz_proto + - grpcpp_channelz_proto uses: - grpc++_test - name: channelz_registry_test @@ -4314,6 +4331,22 @@ targets: uses: - grpc++_test uses_polling: false +- name: channelz_service_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/channelz_service_test.cc + deps: + - grpcpp_channelz + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + filegroups: + - grpcpp_channelz_proto - name: channelz_test gtest: true build: test @@ -4328,7 +4361,7 @@ targets: - gpr_test_util - gpr filegroups: - - grpc++_channelz_proto + - grpcpp_channelz_proto uses: - grpc++_test - name: check_gcp_environment_linux_test diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index f86bd76f328..b3ed9bd7138 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -13,4 +13,5 @@ - 1.11 'g' stands for ['gorgeous'](https://github.com/grpc/grpc/tree/v1.11.x) - 1.12 'g' stands for ['glorious'](https://github.com/grpc/grpc/tree/v1.12.x) - 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/v1.13.x) -- 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/master) +- 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/master) diff --git a/doc/statuscodes.md b/doc/statuscodes.md index f2df9e00dec..06fbe5c8fe8 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -38,6 +38,7 @@ situations in which they are generated. | Error parsing response proto | INTERNAL | Client| | Error parsing request proto | INTERNAL | Server| | Sent or received message was larger than configured limit | RESOURCE_EXHAUSTED | Both | +| Keepalive watchdog times out | INTERNAL | Both | The following status codes are never generated by the library: - INVALID_ARGUMENT @@ -47,3 +48,5 @@ The following status codes are never generated by the library: - ABORTED - OUT_OF_RANGE - DATA_LOSS + +Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 57d58cc4400..1d9237bf627 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.14.0-dev' + # version = '1.15.0-dev' version = '0.0.3' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.14.0-dev' + grpc_version = '1.15.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 997617c5307..23edaec656d 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.14.0-dev' + version = '1.15.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 6548f36a32b..79ec679e3aa 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.14.0-dev' + version = '1.15.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 ebd942cf785..7a461e270f9 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.14.0-dev' + version = '1.15.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 d6d59c21415..bf3f56bd549 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.14.0-dev' + version = '1.15.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/grpc.gyp b/grpc.gyp index 0db6afe4682..e1485efa058 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1585,6 +1585,19 @@ 'src/compiler/ruby_generator.cc', ], }, + { + 'target_name': 'grpcpp_channelz', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + 'grpc', + ], + 'sources': [ + 'src/cpp/server/channelz/channelz_service.cc', + 'src/cpp/server/channelz/channelz_service_plugin.cc', + 'src/proto/grpc/channelz/channelz.proto', + ], + }, { 'target_name': 'http2_client_main', 'type': 'static_library', @@ -1705,6 +1718,7 @@ 'test/cpp/qps/client_sync.cc', 'test/cpp/qps/driver.cc', 'test/cpp/qps/parse_json.cc', + 'test/cpp/qps/qps_server_builder.cc', 'test/cpp/qps/qps_worker.cc', 'test/cpp/qps/report.cc', 'test/cpp/qps/server_async.cc', diff --git a/include/grpcpp/ext/channelz_service_plugin.h b/include/grpcpp/ext/channelz_service_plugin.h new file mode 100644 index 00000000000..af3192d4513 --- /dev/null +++ b/include/grpcpp/ext/channelz_service_plugin.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H +#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H + +#include + +#include +#include +#include + +namespace grpc { +namespace channelz { +namespace experimental { + +/// Add channelz server plugin to \a ServerBuilder. This function should +/// be called at static initialization time. This service is experimental +/// for now. Track progress in https://github.com/grpc/grpc/issues/15988. +void InitChannelzService(); + +} // namespace experimental +} // namespace channelz +} // namespace grpc + +#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H diff --git a/package.xml b/package.xml index a9dc2dc79ac..7f71536b1d0 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.14.0dev - 1.14.0dev + 1.15.0dev + 1.15.0dev beta 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 023281db974..d217dc0e630 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 @@ -451,6 +451,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // latest pending subchannel lists. GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() || subchannel_list() == p->latest_pending_subchannel_list_.get()); + GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN); // Handle updates for the currently selected subchannel. if (p->selected_ == this) { if (grpc_lb_pick_first_trace.enabled()) { @@ -480,14 +481,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( "update"), "selected_not_ready+switch_to_update"); } else { - // TODO(juanlishen): we re-resolve when the selected subchannel goes to - // TRANSIENT_FAILURE because we used to shut down in this case before - // re-resolution is introduced. But we need to investigate whether we - // really want to take any action instead of waiting for the selected - // subchannel reconnecting. - GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN); if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - // If the selected channel goes bad, request a re-resolution. + // If the selected subchannel goes bad, request a re-resolution. We also + // set the channel state to IDLE and reset started_picking_. The reason + // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY + // reception we don't want to connect to the re-resolved backends until + // we leave the IDLE state. grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, "selected_changed+reresolve"); @@ -568,9 +567,10 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // Case 1: Only set state to TRANSIENT_FAILURE if we've tried // all subchannels. if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { + p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); grpc_connectivity_state_set( &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "connecting_transient_failure"); + GRPC_ERROR_REF(error), "exhausted_subchannels"); } sd->StartConnectivityWatchLocked(); break; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 93df2aff700..71ef8c518bb 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -402,8 +402,6 @@ static void continue_connect_locked(grpc_subchannel* c) { c->next_attempt_deadline = c->backoff->NextAttemptTime(); args.deadline = std::max(c->next_attempt_deadline, min_deadline); args.channel_args = c->args; - grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "state_change"); grpc_connector_connect(c->connector, &args, &c->connecting_result, &c->on_connected); } @@ -459,27 +457,24 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { /* Don't try to connect if we're already disconnected */ return; } - if (c->connecting) { /* Already connecting: don't restart */ return; } - if (c->connected_subchannel != nullptr) { /* Already connected: don't restart */ return; } - if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) { /* Nobody is interested in connecting: so don't just yet */ return; } - c->connecting = true; GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); - if (!c->backoff_begun) { c->backoff_begun = true; + grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, + GRPC_ERROR_NONE, "connecting"); continue_connect_locked(c); } else { GPR_ASSERT(!c->have_alarm); @@ -494,6 +489,11 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { } GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); + // During backoff, we prefer the connectivity state of CONNECTING instead of + // TRANSIENT_FAILURE in order to prevent triggering re-resolution + // continuously in pick_first. + grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, + GRPC_ERROR_NONE, "backoff"); } } diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 7581f937b64..35c3fb01eaa 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -82,7 +82,7 @@ typedef struct { typedef struct { grpc_call_stats stats; grpc_status_code final_status; - const char** error_string; + const char* error_string; } grpc_call_final_info; /* Channel filters specify: diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc index 141de69426c..e30b297aeab 100644 --- a/src/core/lib/gpr/arena.cc +++ b/src/core/lib/gpr/arena.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include "src/core/lib/gpr/alloc.h" @@ -36,8 +37,6 @@ #ifdef SIMPLE_ARENA_FOR_DEBUGGING -#include - struct gpr_arena { gpr_mu mu; void** ptrs; @@ -78,14 +77,17 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { // would allow us to use the alignment actually needed by the caller. typedef struct zone { - size_t size_begin; - size_t size_end; - gpr_atm next_atm; + size_t size_begin; // All the space we have set aside for allocations up + // until this zone. + size_t size_end; // size_end = size_begin plus all the space we set aside for + // allocations in zone z itself. + zone* next; } zone; struct gpr_arena { gpr_atm size_so_far; zone initial_zone; + gpr_mu arena_growth_mutex; }; static void* zalloc_aligned(size_t size) { @@ -99,15 +101,17 @@ gpr_arena* gpr_arena_create(size_t initial_size) { gpr_arena* a = static_cast(zalloc_aligned( GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size)); a->initial_zone.size_end = initial_size; + gpr_mu_init(&a->arena_growth_mutex); return a; } size_t gpr_arena_destroy(gpr_arena* arena) { + gpr_mu_destroy(&arena->arena_growth_mutex); gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far); - zone* z = (zone*)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm); + zone* z = arena->initial_zone.next; gpr_free_aligned(arena); while (z) { - zone* next_z = (zone*)gpr_atm_no_barrier_load(&z->next_atm); + zone* next_z = z->next; gpr_free_aligned(z); z = next_z; } @@ -116,37 +120,55 @@ size_t gpr_arena_destroy(gpr_arena* arena) { void* gpr_arena_alloc(gpr_arena* arena, size_t size) { size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); - size_t start = static_cast( + size_t previous_size_of_arena_allocations = static_cast( gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size)); + size_t updated_size_of_arena_allocations = + previous_size_of_arena_allocations + size; zone* z = &arena->initial_zone; - while (start > z->size_end) { - zone* next_z = (zone*)gpr_atm_acq_load(&z->next_atm); - if (next_z == nullptr) { - size_t next_z_size = - static_cast(gpr_atm_no_barrier_load(&arena->size_so_far)); - next_z = static_cast(zalloc_aligned( - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size)); - next_z->size_begin = z->size_end; - next_z->size_end = z->size_end + next_z_size; - if (!gpr_atm_rel_cas(&z->next_atm, static_cast(NULL), - (gpr_atm)next_z)) { - gpr_free_aligned(next_z); - next_z = (zone*)gpr_atm_acq_load(&z->next_atm); + // Check to see if the allocation isn't able to end in the initial zone. + // This statement is true only in the uncommon case because of our arena + // sizing historesis (that is, most calls should have a large enough initial + // zone and will not need to grow the arena). + if (updated_size_of_arena_allocations > z->size_end) { + // Find a zone to fit this allocation + gpr_mu_lock(&arena->arena_growth_mutex); + while (updated_size_of_arena_allocations > z->size_end) { + if (z->next == nullptr) { + // Note that we do an extra increment of size_so_far to prevent multiple + // simultaneous callers from stepping on each other. However, this extra + // increment means some space in the arena is wasted. + // So whenever we need to allocate x bytes and there are x - n (where + // n > 0) remaining in the current zone, we will waste x bytes (x - n + // in the current zone and n in the new zone). + previous_size_of_arena_allocations = static_cast( + gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size)); + updated_size_of_arena_allocations = + previous_size_of_arena_allocations + size; + size_t next_z_size = updated_size_of_arena_allocations; + z->next = static_cast(zalloc_aligned( + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size)); + z->next->size_begin = z->size_end; + z->next->size_end = z->size_end + next_z_size; } + z = z->next; } - z = next_z; - } - if (start + size > z->size_end) { - return gpr_arena_alloc(arena, size); + gpr_mu_unlock(&arena->arena_growth_mutex); } - GPR_ASSERT(start >= z->size_begin); - GPR_ASSERT(start + size <= z->size_end); - char* ptr = (z == &arena->initial_zone) - ? reinterpret_cast(arena) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) - : reinterpret_cast(z) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)); - return ptr + start - z->size_begin; + GPR_ASSERT(previous_size_of_arena_allocations >= z->size_begin); + GPR_ASSERT(updated_size_of_arena_allocations <= z->size_end); + // Skip the first part of the zone, which just contains tracking information. + // For the initial zone, this is the gpr_arena struct and for any other zone, + // it's the zone struct. + char* start_of_allocation_space = + (z == &arena->initial_zone) + ? reinterpret_cast(arena) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + : reinterpret_cast(z) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)); + // previous_size_of_arena_allocations - size_begin is how many bytes have been + // allocated into the current zone + return start_of_allocation_space + previous_size_of_arena_allocations - + z->size_begin; } #endif // SIMPLE_ARENA_FOR_DEBUGGING diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 1ad13b831dd..45d96b80eb4 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -40,19 +40,25 @@ gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \ } +#define EXECUTOR_TRACE0(str) \ + if (executor_trace.enabled()) { \ + gpr_log(GPR_INFO, "EXECUTOR " str); \ + } + grpc_core::TraceFlag executor_trace(false, "executor"); GPR_TLS_DECL(g_this_thread_state); -GrpcExecutor::GrpcExecutor(const char* executor_name) : name_(executor_name) { +GrpcExecutor::GrpcExecutor(const char* name) : name_(name) { adding_thread_lock_ = GPR_SPINLOCK_STATIC_INITIALIZER; - gpr_atm_no_barrier_store(&num_threads_, 0); + gpr_atm_rel_store(&num_threads_, 0); max_threads_ = GPR_MAX(1, 2 * gpr_cpu_num_cores()); } void GrpcExecutor::Init() { SetThreading(true); } -size_t GrpcExecutor::RunClosures(grpc_closure_list list) { +size_t GrpcExecutor::RunClosures(const char* executor_name, + grpc_closure_list list) { size_t n = 0; grpc_closure* c = list.head; @@ -60,11 +66,11 @@ size_t GrpcExecutor::RunClosures(grpc_closure_list list) { grpc_closure* next = c->next_data.next; grpc_error* error = c->error_data.error; #ifndef NDEBUG - EXECUTOR_TRACE("run %p [created by %s:%d]", c, c->file_created, - c->line_created); + EXECUTOR_TRACE("(%s) run %p [created by %s:%d]", executor_name, c, + c->file_created, c->line_created); c->scheduled = false; #else - EXECUTOR_TRACE("run %p", c); + EXECUTOR_TRACE("(%s) run %p", executor_name, c); #endif c->cb(c->cb_arg, error); GRPC_ERROR_UNREF(error); @@ -77,17 +83,21 @@ size_t GrpcExecutor::RunClosures(grpc_closure_list list) { } bool GrpcExecutor::IsThreaded() const { - return gpr_atm_no_barrier_load(&num_threads_) > 0; + return gpr_atm_acq_load(&num_threads_) > 0; } void GrpcExecutor::SetThreading(bool threading) { - gpr_atm curr_num_threads = gpr_atm_no_barrier_load(&num_threads_); + gpr_atm curr_num_threads = gpr_atm_acq_load(&num_threads_); + EXECUTOR_TRACE("(%s) SetThreading(%d) begin", name_, threading); if (threading) { - if (curr_num_threads > 0) return; + if (curr_num_threads > 0) { + EXECUTOR_TRACE("(%s) SetThreading(true). curr_num_threads == 0", name_); + return; + } GPR_ASSERT(num_threads_ == 0); - gpr_atm_no_barrier_store(&num_threads_, 1); + gpr_atm_rel_store(&num_threads_, 1); gpr_tls_init(&g_this_thread_state); thd_state_ = static_cast( gpr_zalloc(sizeof(ThreadState) * max_threads_)); @@ -96,6 +106,7 @@ void GrpcExecutor::SetThreading(bool threading) { gpr_mu_init(&thd_state_[i].mu); gpr_cv_init(&thd_state_[i].cv); thd_state_[i].id = i; + thd_state_[i].name = name_; thd_state_[i].thd = grpc_core::Thread(); thd_state_[i].elems = GRPC_CLOSURE_LIST_INIT; } @@ -104,7 +115,10 @@ void GrpcExecutor::SetThreading(bool threading) { grpc_core::Thread(name_, &GrpcExecutor::ThreadMain, &thd_state_[0]); thd_state_[0].thd.Start(); } else { // !threading - if (curr_num_threads == 0) return; + if (curr_num_threads == 0) { + EXECUTOR_TRACE("(%s) SetThreading(false). curr_num_threads == 0", name_); + return; + } for (size_t i = 0; i < max_threads_; i++) { gpr_mu_lock(&thd_state_[i].mu); @@ -121,20 +135,22 @@ void GrpcExecutor::SetThreading(bool threading) { curr_num_threads = gpr_atm_no_barrier_load(&num_threads_); for (gpr_atm i = 0; i < curr_num_threads; i++) { thd_state_[i].thd.Join(); - EXECUTOR_TRACE(" Thread %" PRIdPTR " of %" PRIdPTR " joined", i, - curr_num_threads); + EXECUTOR_TRACE("(%s) Thread %" PRIdPTR " of %" PRIdPTR " joined", name_, + i + 1, curr_num_threads); } - gpr_atm_no_barrier_store(&num_threads_, 0); + gpr_atm_rel_store(&num_threads_, 0); for (size_t i = 0; i < max_threads_; i++) { gpr_mu_destroy(&thd_state_[i].mu); gpr_cv_destroy(&thd_state_[i].cv); - RunClosures(thd_state_[i].elems); + RunClosures(thd_state_[i].name, thd_state_[i].elems); } gpr_free(thd_state_); gpr_tls_destroy(&g_this_thread_state); } + + EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading); } void GrpcExecutor::Shutdown() { SetThreading(false); } @@ -147,8 +163,8 @@ void GrpcExecutor::ThreadMain(void* arg) { size_t subtract_depth = 0; for (;;) { - EXECUTOR_TRACE("[%" PRIdPTR "]: step (sub_depth=%" PRIdPTR ")", ts->id, - subtract_depth); + EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: step (sub_depth=%" PRIdPTR ")", + ts->name, ts->id, subtract_depth); gpr_mu_lock(&ts->mu); ts->depth -= subtract_depth; @@ -159,7 +175,7 @@ void GrpcExecutor::ThreadMain(void* arg) { } if (ts->shutdown) { - EXECUTOR_TRACE("[%" PRIdPTR "]: shutdown", ts->id); + EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: shutdown", ts->name, ts->id); gpr_mu_unlock(&ts->mu); break; } @@ -169,10 +185,10 @@ void GrpcExecutor::ThreadMain(void* arg) { ts->elems = GRPC_CLOSURE_LIST_INIT; gpr_mu_unlock(&ts->mu); - EXECUTOR_TRACE("[%" PRIdPTR "]: execute", ts->id); + EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: execute", ts->name, ts->id); grpc_core::ExecCtx::Get()->InvalidateNow(); - subtract_depth = RunClosures(closures); + subtract_depth = RunClosures(ts->name, closures); } } @@ -188,16 +204,16 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, do { retry_push = false; size_t cur_thread_count = - static_cast(gpr_atm_no_barrier_load(&num_threads_)); + static_cast(gpr_atm_acq_load(&num_threads_)); // If the number of threads is zero(i.e either the executor is not threaded // or already shutdown), then queue the closure on the exec context itself if (cur_thread_count == 0) { #ifndef NDEBUG - EXECUTOR_TRACE("schedule %p (created %s:%d) inline", closure, + EXECUTOR_TRACE("(%s) schedule %p (created %s:%d) inline", name_, closure, closure->file_created, closure->line_created); #else - EXECUTOR_TRACE("schedule %p inline", closure); + EXECUTOR_TRACE("(%s) schedule %p inline", name_, closure); #endif grpc_closure_list_append(grpc_core::ExecCtx::Get()->closure_list(), closure, error); @@ -213,18 +229,18 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, } ThreadState* orig_ts = ts; - bool try_new_thread = false; + for (;;) { #ifndef NDEBUG EXECUTOR_TRACE( - "try to schedule %p (%s) (created %s:%d) to thread " + "(%s) try to schedule %p (%s) (created %s:%d) to thread " "%" PRIdPTR, - closure, is_short ? "short" : "long", closure->file_created, + name_, closure, is_short ? "short" : "long", closure->file_created, closure->line_created, ts->id); #else - EXECUTOR_TRACE("try to schedule %p (%s) to thread %" PRIdPTR, closure, - is_short ? "short" : "long", ts->id); + EXECUTOR_TRACE("(%s) try to schedule %p (%s) to thread %" PRIdPTR, name_, + closure, is_short ? "short" : "long", ts->id); #endif gpr_mu_lock(&ts->mu); @@ -236,18 +252,22 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, size_t idx = ts->id; ts = &thd_state_[(idx + 1) % cur_thread_count]; if (ts == orig_ts) { - // We cycled through all the threads. Retry enqueue again (by creating - // a new thread) + // We cycled through all the threads. Retry enqueue again by creating + // a new thread + // + // TODO (sreek): There is a potential issue here. We are + // unconditionally setting try_new_thread to true here. What if the + // executor is shutdown OR if cur_thread_count is already equal to + // max_threads ? + // (Fortunately, this is not an issue yet (as of july 2018) because + // there is only one instance of long job in gRPC and hence we will + // not hit this code path) retry_push = true; - // TODO (sreek): What if the executor is shutdown OR if - // cur_thread_count is already equal to max_threads ? (currently - as - // of July 2018, we do not run in to this issue because there is only - // one instance of long job in gRPC. This has to be fixed soon) try_new_thread = true; break; } - continue; + continue; // Try the next thread-state } // == Found the thread state (i.e thread) to enqueue this closure! == @@ -277,13 +297,11 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, } if (try_new_thread && gpr_spinlock_trylock(&adding_thread_lock_)) { - cur_thread_count = - static_cast(gpr_atm_no_barrier_load(&num_threads_)); + cur_thread_count = static_cast(gpr_atm_acq_load(&num_threads_)); if (cur_thread_count < max_threads_) { - // Increment num_threads (Safe to do a no_barrier_store instead of a - // cas because we always increment num_threads under the - // 'adding_thread_lock') - gpr_atm_no_barrier_store(&num_threads_, cur_thread_count + 1); + // Increment num_threads (safe to do a store instead of a cas because we + // always increment num_threads under the 'adding_thread_lock') + gpr_atm_rel_store(&num_threads_, cur_thread_count + 1); thd_state_[cur_thread_count].thd = grpc_core::Thread( name_, &GrpcExecutor::ThreadMain, &thd_state_[cur_thread_count]); @@ -298,60 +316,118 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, } while (retry_push); } -static GrpcExecutor* global_executor; +static GrpcExecutor* executors[GRPC_NUM_EXECUTORS]; -void enqueue_long(grpc_closure* closure, grpc_error* error) { - global_executor->Enqueue(closure, error, false /* is_short */); +void default_enqueue_short(grpc_closure* closure, grpc_error* error) { + executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error, + true /* is_short */); } -void enqueue_short(grpc_closure* closure, grpc_error* error) { - global_executor->Enqueue(closure, error, true /* is_short */); +void default_enqueue_long(grpc_closure* closure, grpc_error* error) { + executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error, + false /* is_short */); } -// Short-Job executor scheduler -static const grpc_closure_scheduler_vtable global_executor_vtable_short = { - enqueue_short, enqueue_short, "executor-short"}; -static grpc_closure_scheduler global_scheduler_short = { - &global_executor_vtable_short}; +void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) { + executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error, + true /* is_short */); +} -// Long-job executor scheduler -static const grpc_closure_scheduler_vtable global_executor_vtable_long = { - enqueue_long, enqueue_long, "executor-long"}; -static grpc_closure_scheduler global_scheduler_long = { - &global_executor_vtable_long}; +void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) { + executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error, + false /* is_short */); +} + +static const grpc_closure_scheduler_vtable + vtables_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = { + {{&default_enqueue_short, &default_enqueue_short, "def-ex-short"}, + {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}}, + {{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"}, + {&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}}; + +static grpc_closure_scheduler + schedulers_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = { + {{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_SHORT]}, + {&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_LONG]}}, + {{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_SHORT]}, + {&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_LONG]}}}; // grpc_executor_init() and grpc_executor_shutdown() functions are called in the // the grpc_init() and grpc_shutdown() code paths which are protected by a // global mutex. So it is okay to assume that these functions are thread-safe void grpc_executor_init() { - if (global_executor != nullptr) { - // grpc_executor_init() already called once (and grpc_executor_shutdown() - // wasn't called) + EXECUTOR_TRACE0("grpc_executor_init() enter"); + + // Return if grpc_executor_init() is already called earlier + if (executors[GRPC_DEFAULT_EXECUTOR] != nullptr) { + GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] != nullptr); return; } - global_executor = grpc_core::New("global-executor"); - global_executor->Init(); + executors[GRPC_DEFAULT_EXECUTOR] = + grpc_core::New("default-executor"); + executors[GRPC_RESOLVER_EXECUTOR] = + grpc_core::New("resolver-executor"); + + executors[GRPC_DEFAULT_EXECUTOR]->Init(); + executors[GRPC_RESOLVER_EXECUTOR]->Init(); + + EXECUTOR_TRACE0("grpc_executor_init() done"); +} + +grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, + GrpcExecutorJobType job_type) { + return &schedulers_[executor_type][job_type]; +} + +grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) { + return grpc_executor_scheduler(GRPC_DEFAULT_EXECUTOR, job_type); } void grpc_executor_shutdown() { - // Shutdown already called - if (global_executor == nullptr) { + EXECUTOR_TRACE0("grpc_executor_shutdown() enter"); + + // Return if grpc_executor_shutdown() is already called earlier + if (executors[GRPC_DEFAULT_EXECUTOR] == nullptr) { + GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] == nullptr); return; } - global_executor->Shutdown(); - grpc_core::Delete(global_executor); - global_executor = nullptr; + executors[GRPC_DEFAULT_EXECUTOR]->Shutdown(); + executors[GRPC_RESOLVER_EXECUTOR]->Shutdown(); + + // Delete the executor objects. + // + // NOTE: It is important to call Shutdown() on all executors first before + // calling Delete() because it is possible for one executor (that is not + // shutdown yet) to call Enqueue() on a different executor which is already + // shutdown. This is legal and in such cases, the Enqueue() operation + // effectively "fails" and enqueues that closure on the calling thread's + // exec_ctx. + // + // By ensuring that all executors are shutdown first, we are also ensuring + // that no thread is active across all executors. + + grpc_core::Delete(executors[GRPC_DEFAULT_EXECUTOR]); + grpc_core::Delete(executors[GRPC_RESOLVER_EXECUTOR]); + executors[GRPC_DEFAULT_EXECUTOR] = nullptr; + executors[GRPC_RESOLVER_EXECUTOR] = nullptr; + + EXECUTOR_TRACE0("grpc_executor_shutdown() done"); } -bool grpc_executor_is_threaded() { return global_executor->IsThreaded(); } +bool grpc_executor_is_threaded(GrpcExecutorType executor_type) { + GPR_ASSERT(executor_type < GRPC_NUM_EXECUTORS); + return executors[executor_type]->IsThreaded(); +} -void grpc_executor_set_threading(bool enable) { - global_executor->SetThreading(enable); +bool grpc_executor_is_threaded() { + return grpc_executor_is_threaded(GRPC_DEFAULT_EXECUTOR); } -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) { - return job_type == GRPC_EXECUTOR_SHORT ? &global_scheduler_short - : &global_scheduler_long; +void grpc_executor_set_threading(bool enable) { + EXECUTOR_TRACE("grpc_executor_set_threading(%d) called", enable); + for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) { + executors[i]->SetThreading(enable); + } } diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h index 395fc528637..8829138c5fa 100644 --- a/src/core/lib/iomgr/executor.h +++ b/src/core/lib/iomgr/executor.h @@ -27,7 +27,8 @@ typedef struct { gpr_mu mu; - size_t id; // For debugging purposes + size_t id; // For debugging purposes + const char* name; // Thread state name gpr_cv cv; grpc_closure_list elems; size_t depth; // Number of closures in the closure list @@ -36,7 +37,11 @@ typedef struct { grpc_core::Thread thd; } ThreadState; -typedef enum { GRPC_EXECUTOR_SHORT, GRPC_EXECUTOR_LONG } GrpcExecutorJobType; +typedef enum { + GRPC_EXECUTOR_SHORT = 0, + GRPC_EXECUTOR_LONG, + GRPC_NUM_EXECUTOR_JOB_TYPES // Add new values above this +} GrpcExecutorJobType; class GrpcExecutor { public: @@ -58,7 +63,7 @@ class GrpcExecutor { void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short); private: - static size_t RunClosures(grpc_closure_list list); + static size_t RunClosures(const char* executor_name, grpc_closure_list list); static void ThreadMain(void* arg); const char* name_; @@ -70,14 +75,42 @@ class GrpcExecutor { // == Global executor functions == +typedef enum { + GRPC_DEFAULT_EXECUTOR = 0, + GRPC_RESOLVER_EXECUTOR, + + GRPC_NUM_EXECUTORS // Add new values above this +} GrpcExecutorType; + +// TODO(sreek): Currently we have two executors (available globally): The +// default executor and the resolver executor. +// +// Some of the functions below operate on the DEFAULT executor only while some +// operate of ALL the executors. This is a bit confusing and should be cleaned +// up in future (where we make all the following functions take executor_type +// and/or job_type) + +// Initialize ALL the executors void grpc_executor_init(); +// Shutdown ALL the executors +void grpc_executor_shutdown(); + +// Set the threading mode for ALL the executors +void grpc_executor_set_threading(bool enable); + +// Get the DEFAULT executor scheduler for the given job_type grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type); -void grpc_executor_shutdown(); +// Get the executor scheduler for a given executor_type and a job_type +grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, + GrpcExecutorJobType job_type); -bool grpc_executor_is_threaded(); +// Return if a given executor is running in threaded mode (i.e if +// grpc_executor_set_threading(true) was called previously on that executor) +bool grpc_executor_is_threaded(GrpcExecutorType executor_type); -void grpc_executor_set_threading(bool enable); +// Return if the DEFAULT executor is threaded +bool grpc_executor_is_threaded(); #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */ diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index 7a825643e12..c285d7eca66 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -166,8 +166,9 @@ static void posix_resolve_address(const char* name, const char* default_port, grpc_closure* on_done, grpc_resolved_addresses** addrs) { request* r = static_cast(gpr_malloc(sizeof(request))); - GRPC_CLOSURE_INIT(&r->request_closure, do_request_thread, r, - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT)); + GRPC_CLOSURE_INIT( + &r->request_closure, do_request_thread, r, + grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT)); r->name = gpr_strdup(name); r->default_port = gpr_strdup(default_port); r->on_done = on_done; diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index 71c92615ad6..3e977dca2da 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -151,8 +151,9 @@ static void windows_resolve_address(const char* name, const char* default_port, grpc_closure* on_done, grpc_resolved_addresses** addresses) { request* r = (request*)gpr_malloc(sizeof(request)); - GRPC_CLOSURE_INIT(&r->request_closure, do_request_thread, r, - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT)); + GRPC_CLOSURE_INIT( + &r->request_closure, do_request_thread, r, + grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT)); r->name = gpr_strdup(name); r->default_port = gpr_strdup(default_port); r->on_done = on_done; diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc index 7c4d7a71cd1..8454fd7558c 100644 --- a/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc +++ b/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc @@ -41,8 +41,9 @@ namespace internal { bool check_bios_data(const char* bios_data_file) { char* bios_data = read_bios_file(bios_data_file); - bool result = (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE)) || - (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GCE)); + bool result = + bios_data && ((!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE)) || + (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GCE))); gpr_free(bios_data); return result; } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index cc72bb61649..59cf3a0af18 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -57,6 +57,10 @@ static const char* installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem"; #endif +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + /* -- Overridden default roots. -- */ static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr; @@ -850,7 +854,8 @@ grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { static grpc_error* ssl_check_peer(grpc_security_connector* sc, const char* peer_name, const tsi_peer* peer, grpc_auth_context** auth_context) { - /* Check the ALPN. */ +#if TSI_OPENSSL_ALPN_SUPPORT + /* Check the ALPN if ALPN is supported. */ const tsi_peer_property* p = tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); if (p == nullptr) { @@ -861,7 +866,7 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Cannot check peer: invalid ALPN value."); } - +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ /* Check the peer name if specified. */ if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { char* msg; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 88e015ce22f..847bb87f7e5 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -561,7 +561,7 @@ static void destroy_call(void* call, grpc_error* error) { } get_final_status(c, set_status_value_directly, &c->final_info.final_status, - nullptr, c->final_info.error_string); + nullptr, &(c->final_info.error_string)); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); @@ -573,6 +573,7 @@ static void destroy_call(void* call, grpc_error* error) { grpc_call_stack_destroy(CALL_STACK_FROM_CALL(c), &c->final_info, GRPC_CLOSURE_INIT(&c->release_call, release_call, c, grpc_schedule_on_exec_ctx)); + gpr_free(static_cast(const_cast(c->final_info.error_string))); } void grpc_call_ref(grpc_call* c) { gpr_ref(&c->ext_ref); } diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index ac8cec29804..e92fe2c5a15 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 "6.0.0-dev"; } -const char* grpc_g_stands_for(void) { return "gladiolus"; } +const char* grpc_g_stands_for(void) { return "glider"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index a7b093dfd2a..b8fca9a6ee3 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.14.0-dev"; } +grpc::string Version() { return "1.15.0-dev"; } } // namespace grpc diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc new file mode 100644 index 00000000000..77c175e5b8f --- /dev/null +++ b/src/cpp/server/channelz/channelz_service.cc @@ -0,0 +1,57 @@ +/* + * + * 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/cpp/server/channelz/channelz_service.h" + +#include +#include + +#include +#include + +namespace grpc { + +Status ChannelzService::GetTopChannels( + ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, + channelz::v1::GetTopChannelsResponse* response) { + char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); + google::protobuf::util::Status s = + google::protobuf::util::JsonStringToMessage(json_str, response); + gpr_free(json_str); + if (s != google::protobuf::util::Status::OK) { + return Status(INTERNAL, s.ToString()); + } + return Status::OK; +} + +Status ChannelzService::GetChannel( + ServerContext* unused, const channelz::v1::GetChannelRequest* request, + channelz::v1::GetChannelResponse* response) { + char* json_str = grpc_channelz_get_channel(request->channel_id()); + google::protobuf::util::Status s = + google::protobuf::util::JsonStringToMessage(json_str, response); + gpr_free(json_str); + if (s != google::protobuf::util::Status::OK) { + return Status(INTERNAL, s.ToString()); + } + return Status::OK; +} + +} // namespace grpc diff --git a/src/cpp/server/channelz/channelz_service.h b/src/cpp/server/channelz/channelz_service.h new file mode 100644 index 00000000000..f619ea49e04 --- /dev/null +++ b/src/cpp/server/channelz/channelz_service.h @@ -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. + * + */ + +#ifndef GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H +#define GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H + +#include + +#include +#include "src/proto/grpc/channelz/channelz.grpc.pb.h" + +namespace grpc { + +class ChannelzService final : public channelz::v1::Channelz::Service { + private: + // implementation of GetTopChannels rpc + Status GetTopChannels( + ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, + channelz::v1::GetTopChannelsResponse* response) override; + // implementation of GetChannel rpc + Status GetChannel(ServerContext* unused, + const channelz::v1::GetChannelRequest* request, + channelz::v1::GetChannelResponse* response) override; +}; + +} // namespace grpc + +#endif // GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H diff --git a/src/cpp/server/channelz/channelz_service_plugin.cc b/src/cpp/server/channelz/channelz_service_plugin.cc new file mode 100644 index 00000000000..b93e5b551e1 --- /dev/null +++ b/src/cpp/server/channelz/channelz_service_plugin.cc @@ -0,0 +1,79 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include +#include +#include +#include + +#include "src/cpp/server/channelz/channelz_service.h" + +namespace grpc { +namespace channelz { +namespace experimental { + +class ChannelzServicePlugin : public ::grpc::ServerBuilderPlugin { + public: + ChannelzServicePlugin() : channelz_service_(new grpc::ChannelzService()) {} + + grpc::string name() override { return "channelz_service"; } + + void InitServer(grpc::ServerInitializer* si) override { + si->RegisterService(channelz_service_); + } + + void Finish(grpc::ServerInitializer* si) override {} + + void ChangeArguments(const grpc::string& name, void* value) override {} + + bool has_sync_methods() const override { + if (channelz_service_) { + return channelz_service_->has_synchronous_methods(); + } + return false; + } + + bool has_async_methods() const override { + if (channelz_service_) { + return channelz_service_->has_async_methods(); + } + return false; + } + + private: + std::shared_ptr channelz_service_; +}; + +static std::unique_ptr< ::grpc::ServerBuilderPlugin> +CreateChannelzServicePlugin() { + return std::unique_ptr< ::grpc::ServerBuilderPlugin>( + new ChannelzServicePlugin()); +} + +void InitChannelzService() { + static bool already_here = false; + if (already_here) return; + already_here = true; + ::grpc::ServerBuilder::InternalAddPluginFactory(&CreateChannelzServicePlugin); +} + +} // namespace experimental +} // namespace channelz +} // namespace grpc diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 6d44be7ddd6..fc32271063f 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -46,10 +46,38 @@ runtimes/win/native/grpc_csharp_ext.x86.dll true - + + runtimes/monoandroid/armeabi-v7a/libgrpc_csharp_ext.so + true + + + runtimes/monoandroid/arm64-v8a/libgrpc_csharp_ext.so + true + + + runtimes/monoandroid/x86/libgrpc_csharp_ext.so + true + + + runtimes/ios/native/libgrpc_csharp_ext.a + true + + + runtimes/ios/native/libgrpc.a + true + + build/net45/ true + + build/MonoAndroid/ + true + + + build/Xamarin.iOS/ + true + diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index d5ec998bbdb..f526b913af0 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -106,7 +106,15 @@ namespace Grpc.Core.Internal /// private static NativeMethods LoadNativeMethods() { - return PlatformApis.IsUnity ? LoadNativeMethodsUnity() : new NativeMethods(LoadUnmanagedLibrary()); + if (PlatformApis.IsUnity) + { + return LoadNativeMethodsUnity(); + } + if (PlatformApis.IsXamarin) + { + return LoadNativeMethodsXamarin(); + } + return new NativeMethods(LoadUnmanagedLibrary()); } /// @@ -128,6 +136,20 @@ namespace Grpc.Core.Internal } } + /// + /// Return native method delegates when running on the Xamarin platform. + /// WARNING: Xamarin support is experimental and work-in-progress. Don't expect it to work. + /// + private static NativeMethods LoadNativeMethodsXamarin() + { + if (PlatformApis.IsXamarinAndroid) + { + return new NativeMethods(new NativeMethods.DllImportsFromSharedLib()); + } + // not tested yet + return new NativeMethods(new NativeMethods.DllImportsFromStaticLib()); + } + private static string GetAssemblyPath() { var assembly = typeof(NativeExtension).GetTypeInfo().Assembly; diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs index bf6440123a6..30264acb10b 100644 --- a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs +++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs @@ -51,6 +51,7 @@ namespace Grpc.Core.Internal } } + [MonoPInvokeCallback(typeof(GprLogDelegate))] private static void HandleWrite(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr) { try @@ -86,4 +87,22 @@ namespace Grpc.Core.Internal } } } + + /// + /// Use this attribute to mark methods that will be called back from P/Invoke calls. + /// iOS (and probably other AOT platforms) needs to have delegates registered. + /// Instead of depending on Xamarin.iOS for this, we can just create our own, + /// the iOS runtime just checks for the type name. + /// See: https://docs.microsoft.com/en-gb/xamarin/ios/internals/limitations#reverse-callbacks + /// + [AttributeUsage(AttributeTargets.Method)] + internal sealed class MonoPInvokeCallbackAttribute : Attribute + { + public MonoPInvokeCallbackAttribute(Type type) + { + Type = type; + } + + public Type Type { get; private set; } + } } diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs index b90fbccb2bd..c501aa89fb6 100644 --- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs +++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs @@ -33,12 +33,18 @@ namespace Grpc.Core.Internal internal static class PlatformApis { const string UnityEngineApplicationClassName = "UnityEngine.Application, UnityEngine"; + const string XamarinAndroidObjectClassName = "Java.Lang.Object, Mono.Android"; + const string XamarinIOSObjectClassName = "Foundation.NSObject, Xamarin.iOS"; + static readonly bool isLinux; static readonly bool isMacOSX; static readonly bool isWindows; static readonly bool isMono; static readonly bool isNetCore; static readonly bool isUnity; + static readonly bool isXamarin; + static readonly bool isXamarinIOS; + static readonly bool isXamarinAndroid; static PlatformApis() { @@ -58,6 +64,9 @@ namespace Grpc.Core.Internal #endif isMono = Type.GetType("Mono.Runtime") != null; isUnity = Type.GetType(UnityEngineApplicationClassName) != null; + isXamarinIOS = Type.GetType(XamarinIOSObjectClassName) != null; + isXamarinAndroid = Type.GetType(XamarinAndroidObjectClassName) != null; + isXamarin = isXamarinIOS || isXamarinAndroid; } public static bool IsLinux @@ -88,6 +97,31 @@ namespace Grpc.Core.Internal get { return isUnity; } } + /// + /// true if running on a Xamarin platform (either Xamarin.Android or Xamarin.iOS), + /// false otherwise. + /// + public static bool IsXamarin + { + get { return isXamarin; } + } + + /// + /// true if running on Xamarin.iOS, false otherwise. + /// + public static bool IsXamarinIOS + { + get { return isXamarinIOS; } + } + + /// + /// true if running on Xamarin.Android, false otherwise. + /// + public static bool IsXamarinAndroid + { + get { return isXamarinAndroid; } + } + /// /// true if running on .NET Core (CoreCLR), false otherwise. /// diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 2b45e7ae203..1a746acdd4f 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.14.0-dev + 1.15.0-dev 3.5.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index c4531e5275a..295e0f2577b 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.14.0.0"; + public const string CurrentAssemblyFileVersion = "1.15.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.14.0-dev"; + public const string CurrentVersion = "1.15.0-dev"; } } diff --git a/src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets b/src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets new file mode 100644 index 00000000000..d75e5a2f2f9 --- /dev/null +++ b/src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets @@ -0,0 +1,28 @@ + + + + <_GrpcCoreNugetNativePath Condition="'$(_GrpcCoreNugetNativePath)' == ''">$(MSBuildThisFileDirectory)..\..\ + + + + + Always + arm64-v8a + + + + + + Always + armeabi-v7a + + + + + + Always + x86 + + + + diff --git a/src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets b/src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets new file mode 100644 index 00000000000..658158f6ea9 --- /dev/null +++ b/src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets @@ -0,0 +1,15 @@ + + + + + + Static + True + + + Static + True + + + + diff --git a/src/csharp/Grpc.Core/Grpc.Core.targets b/src/csharp/Grpc.Core/build/net45/Grpc.Core.targets similarity index 100% rename from src/csharp/Grpc.Core/Grpc.Core.targets rename to src/csharp/Grpc.Core/build/net45/Grpc.Core.targets diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 394b859e0be..67af258354f 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.14.0-dev +set VERSION=1.15.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh index 273d745f170..88b4d63538d 100755 --- a/src/csharp/build_packages_dotnetcli.sh +++ b/src/csharp/build_packages_dotnetcli.sh @@ -45,8 +45,8 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts -nuget pack Grpc.nuspec -Version "1.14.0-dev" -OutputDirectory ../../artifacts -nuget pack Grpc.Core.NativeDebug.nuspec -Version "1.14.0-dev" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.14.0-dev" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.15.0-dev" -OutputDirectory ../../artifacts +nuget pack Grpc.Core.NativeDebug.nuspec -Version "1.15.0-dev" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.15.0-dev" -OutputDirectory ../../artifacts (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg) diff --git a/src/csharp/experimental/build_native_ext_for_android.sh b/src/csharp/experimental/build_native_ext_for_android.sh index 8197df7c536..6518e03c53e 100755 --- a/src/csharp/experimental/build_native_ext_for_android.sh +++ b/src/csharp/experimental/build_native_ext_for_android.sh @@ -23,17 +23,30 @@ mkdir -p build cd build # set to the location where Android SDK is installed -# e.g. ANDROID_NDK_PATH="$HOME/android-ndk-r16b" +# e.g. ANDROID_SDK_PATH="$HOME/Android/Sdk" -cmake ../.. \ - -DCMAKE_SYSTEM_NAME=Android \ - -DCMAKE_SYSTEM_VERSION=15 \ - -DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a \ +# set to location where Android NDK is installed, usually a subfolder of Android SDK +# to install the Android NKD, use the "sdkmanager" tool +# e.g. ANDROID_NDK_PATH=${ANDROID_SDK_PATH}/ndk-bundle + +# set to location of the cmake executable from the Android SDK +# to install cmake, use the "sdkmanager" tool +# e.g. ANDROID_SDK_CMAKE=${ANDROID_SDK_PATH}/cmake/3.6.4111459/bin/cmake + +# ANDROID_ABI in ('arm64-v8a', 'armeabi-v7a') +# e.g. ANDROID_ABI=armeabi-v7a + +# android-19 corresponds to Kitkat 4.4 +${ANDROID_SDK_CMAKE} ../.. \ + -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake" \ -DCMAKE_ANDROID_NDK="${ANDROID_NDK_PATH}" \ -DCMAKE_ANDROID_STL_TYPE=c++_static \ -DRUN_HAVE_POSIX_REGEX=0 \ -DRUN_HAVE_STD_REGEX=0 \ -DRUN_HAVE_STEADY_CLOCK=0 \ - -DCMAKE_BUILD_TYPE=Release + -DCMAKE_BUILD_TYPE=Release \ + -DANDROID_PLATFORM=android-19 \ + -DANDROID_ABI="${ANDROID_ABI}" \ + -DANDROID_NDK="${ANDROID_NDK_PATH}" make -j4 grpc_csharp_ext diff --git a/src/csharp/experimental/build_native_ext_for_ios.sh b/src/csharp/experimental/build_native_ext_for_ios.sh new file mode 100755 index 00000000000..69c9cdf021c --- /dev/null +++ b/src/csharp/experimental/build_native_ext_for_ios.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# 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. + +# Helper script to crosscompile grpc_csharp_ext native extension for Android. + +set -ex + +cd "$(dirname "$0")/../../.." + +# Usage: build +function build { + SDK="$1" + ARCH="$2" + + PATH_AR="$(xcrun --sdk $SDK --find ar)" + PATH_CC="$(xcrun --sdk $SDK --find clang)" + PATH_CXX="$(xcrun --sdk $SDK --find clang++)" + + # TODO(jtattermusch): add -mios-version-min=6.0 and -Wl,ios_version_min=6.0 + CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -DPB_NO_PACKED_STRUCTS=1" + LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path)" + + # TODO(jtattermusch): revisit the build arguments + make -j4 static_csharp \ + VALID_CONFIG_ios_$ARCH="1" \ + CC_ios_$ARCH="$PATH_CC" \ + CXX_ios_$ARCH="$PATH_CXX" \ + LD_ios_$ARCH="$PATH_CC" \ + LDXX_ios_$ARCH="$PATH_CXX" \ + CPPFLAGS_ios_$ARCH="$CPPFLAGS" \ + LDFLAGS_ios_$ARCH="$LDFLAGS" \ + DEFINES_ios_$ARCH="NDEBUG" \ + CONFIG="ios_$ARCH" +} + +# Usage: fatten +function fatten { + LIB_NAME="$1" + + mkdir -p libs/ios + lipo -create -output libs/ios/lib$LIB_NAME.a \ + libs/ios_arm64/lib$LIB_NAME.a \ + libs/ios_x86_64/lib$LIB_NAME.a +} + +build iphoneos arm64 +build iphonesimulator x86_64 + +fatten grpc +fatten grpc_csharp_ext diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 28dfffd8631..6ad9166b32e 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.14.0-dev' + v = '1.15.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 60571b1f43f..52fe0dd0502 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.14.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index fafcac6507d..d532eed245d 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.14.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev" #define GRPC_C_VERSION_STRING @"6.0.0-dev" diff --git a/src/php/composer.json b/src/php/composer.json index 94918417d9f..b6716b8b4c3 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.14.0", + "version": "1.15.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index c985863cb59..99dd9d68f05 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.14.0dev" +#define PHP_GRPC_VERSION "1.15.0dev" #endif /* VERSION_H */ diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index ecb419ac8f8..fe81e377610 100644 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -83,10 +83,11 @@ class BaseStub } private static function updateOpts($opts) { - $package_config = json_decode( - file_get_contents(dirname(__FILE__).'/../../composer.json'), - true - ); + if (!file_exists($composerFile = __DIR__.'/../../composer.json')) { + // for grpc/grpc-php subpackage + $composerFile = __DIR__.'/../composer.json'; + } + $package_config = json_decode(file_get_contents($composerFile), true); if (!empty($opts['grpc.primary_user_agent'])) { $opts['grpc.primary_user_agent'] .= ' '; } else { diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index 5396a2fd39a..2f935304ab2 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -46,6 +46,7 @@ message RequestParams { string binary_error_details = 13; ErrorStatus expected_error = 14; int32 server_sleep_us = 15; // Amount to sleep when invoking server + int32 backend_channel_idx = 16; // which backend to send request to } message EchoRequest { diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index b336e6aae54..c33911ebc1b 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.14.0.dev0""" +__version__ = """1.15.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2eeaabc8b88..9337800a332 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.14.0.dev0' +VERSION = '1.15.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index f36de8d0fa1..3b84f7a4c55 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.14.0.dev0' +VERSION = '1.15.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 2249b07d9d7..7b0e48ea23b 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.14.0.dev0' +VERSION = '1.15.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index a5b275aff65..df9953fa257 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.14.0.dev0' +VERSION = '1.15.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 816dfb55bc1..b2cf129e4fb 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.14.0.dev0' +VERSION = '1.15.0.dev0' diff --git a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py index aebee4da965..e0422627962 100644 --- a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py +++ b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py @@ -41,6 +41,7 @@ class _Callback(object): return self._value +@unittest.skip('https://github.com/grpc/grpc/issues/16134') class ChannelConnectivityTest(unittest.TestCase): def test_lonely_channel_connectivity(self): diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 4760f33e389..df8acc1bc26 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -110,7 +110,7 @@ if grpc_config == 'opt' o.puts i end o.puts - o.puts 'strip:' + o.puts 'strip: $(DLLIB)' o.puts "\t$(ECHO) Stripping $(DLLIB)" o.puts "\t$(Q) #{strip_tool} $(DLLIB)" end diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 902d59bd71a..5c21a5b1685 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.14.0.dev' + VERSION = '1.15.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index dad09bb965e..1b5e2c362be 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.14.0.dev' + VERSION = '1.15.0.dev' end end diff --git a/templates/Makefile.template b/templates/Makefile.template index 628056ed4db..50b81e5f9f2 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -921,6 +921,16 @@ % endfor + static_csharp: static_c \ + % for lib in libs: + % if 'Makefile' in lib.get('build_system', ['Makefile']): + % if lib.build == 'all' and lib.language == 'csharp': + $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\ + % endif + % endif + % endfor + + shared: shared_c shared_cxx shared_c: pc_c pc_c_unsecure cache.mk\ diff --git a/test/core/security/check_gcp_environment_linux_test.cc b/test/core/security/check_gcp_environment_linux_test.cc index 3acd5b6ae48..b01471abd34 100644 --- a/test/core/security/check_gcp_environment_linux_test.cc +++ b/test/core/security/check_gcp_environment_linux_test.cc @@ -69,6 +69,7 @@ static void test_gcp_environment_check_failure() { GPR_ASSERT(!check_bios_data_linux_test("Amazon")); GPR_ASSERT(!check_bios_data_linux_test("Google-Chrome\t\t")); GPR_ASSERT(!check_bios_data_linux_test("Amazon")); + GPR_ASSERT(!check_bios_data_linux_test("\n")); } int main(int argc, char** argv) { diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 95bb7ed229d..75dec56a602 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -119,6 +119,27 @@ grpc_cc_library( ], ) +grpc_cc_test( + name = "channelz_service_test", + srcs = ["channelz_service_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpcpp_channelz", + "//src/proto/grpc/channelz:channelz_proto", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "server_early_return_test", srcs = ["server_early_return_test.cc"], diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc new file mode 100644 index 00000000000..933e4a1ff67 --- /dev/null +++ b/test/cpp/end2end/channelz_service_test.cc @@ -0,0 +1,352 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "src/proto/grpc/channelz/channelz.grpc.pb.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include + +using grpc::channelz::v1::GetChannelRequest; +using grpc::channelz::v1::GetChannelResponse; +using grpc::channelz::v1::GetTopChannelsRequest; +using grpc::channelz::v1::GetTopChannelsResponse; + +namespace grpc { +namespace testing { +namespace { + +// Proxy service supports N backends. Sends RPC to backend dictated by +// request->backend_channel_idx(). +class Proxy : public ::grpc::testing::EchoTestService::Service { + public: + Proxy() {} + + void AddChannelToBackend(const std::shared_ptr& channel) { + stubs_.push_back(grpc::testing::EchoTestService::NewStub(channel)); + } + + Status Echo(ServerContext* server_context, const EchoRequest* request, + EchoResponse* response) override { + std::unique_ptr client_context = + ClientContext::FromServerContext(*server_context); + size_t idx = request->param().backend_channel_idx(); + GPR_ASSERT(idx < stubs_.size()); + return stubs_[idx]->Echo(client_context.get(), *request, response); + } + + private: + std::vector> stubs_; +}; + +} // namespace + +class ChannelzServerTest : public ::testing::Test { + public: + ChannelzServerTest() {} + + void SetUp() override { + // ensure channel server is brought up on all severs we build. + ::grpc::channelz::experimental::InitChannelzService(); + + // We set up a proxy server with channelz enabled. + proxy_port_ = grpc_pick_unused_port_or_die(); + ServerBuilder proxy_builder; + grpc::string proxy_server_address = "localhost:" + to_string(proxy_port_); + proxy_builder.AddListeningPort(proxy_server_address, + InsecureServerCredentials()); + // forces channelz and channel tracing to be enabled. + proxy_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 1); + proxy_builder.AddChannelArgument(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, + 10); + proxy_builder.RegisterService(&proxy_service_); + proxy_server_ = proxy_builder.BuildAndStart(); + } + + // Sets the proxy up to have an arbitrary number of backends. + void ConfigureProxy(size_t num_backends) { + backends_.resize(num_backends); + for (size_t i = 0; i < num_backends; ++i) { + // create a new backend. + backends_[i].port = grpc_pick_unused_port_or_die(); + ServerBuilder backend_builder; + grpc::string backend_server_address = + "localhost:" + to_string(backends_[i].port); + backend_builder.AddListeningPort(backend_server_address, + InsecureServerCredentials()); + backends_[i].service.reset(new TestServiceImpl); + // ensure that the backend itself has channelz disabled. + backend_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 0); + backend_builder.RegisterService(backends_[i].service.get()); + backends_[i].server = backend_builder.BuildAndStart(); + // set up a channel to the backend. We ensure that this channel has + // channelz enabled since these channels (proxy outbound to backends) + // are the ones that our test will actually be validating. + ChannelArguments args; + args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); + args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, 10); + std::shared_ptr channel_to_backend = CreateCustomChannel( + backend_server_address, InsecureChannelCredentials(), args); + proxy_service_.AddChannelToBackend(channel_to_backend); + } + } + + void ResetStubs() { + string target = "dns:localhost:" + to_string(proxy_port_); + ChannelArguments args; + // disable channelz. We only want to focus on proxy to backend outbound. + args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); + std::shared_ptr channel = + CreateCustomChannel(target, InsecureChannelCredentials(), args); + channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); + echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); + } + + void SendSuccessfulEcho(int channel_idx) { + EchoRequest request; + EchoResponse response; + request.set_message("Hello channelz"); + request.mutable_param()->set_backend_channel_idx(channel_idx); + ClientContext context; + Status s = echo_stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); + } + + void SendFailedEcho(int channel_idx) { + EchoRequest request; + EchoResponse response; + request.set_message("Hello channelz"); + request.mutable_param()->set_backend_channel_idx(channel_idx); + auto* error = request.mutable_param()->mutable_expected_error(); + error->set_code(13); // INTERNAL + error->set_error_message("error"); + ClientContext context; + Status s = echo_stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + } + + static string to_string(const int number) { + std::stringstream strs; + strs << number; + return strs.str(); + } + + protected: + // package of data needed for each backend server. + struct BackendData { + std::unique_ptr server; + int port; + std::unique_ptr service; + }; + + std::unique_ptr channelz_stub_; + std::unique_ptr echo_stub_; + + // proxy server to ping with channelz requests. + std::unique_ptr proxy_server_; + int proxy_port_; + Proxy proxy_service_; + + // backends. All implement the echo service. + std::vector backends_; +}; + +TEST_F(ChannelzServerTest, BasicTest) { + ResetStubs(); + ConfigureProxy(1); + GetTopChannelsRequest request; + GetTopChannelsResponse response; + request.set_start_channel_id(0); + ClientContext context; + Status s = channelz_stub_->GetTopChannels(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel_size(), 1); +} + +TEST_F(ChannelzServerTest, HighStartId) { + ResetStubs(); + ConfigureProxy(1); + GetTopChannelsRequest request; + GetTopChannelsResponse response; + request.set_start_channel_id(10000); + ClientContext context; + Status s = channelz_stub_->GetTopChannels(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel_size(), 0); +} + +TEST_F(ChannelzServerTest, SuccessfulRequestTest) { + ResetStubs(); + ConfigureProxy(1); + SendSuccessfulEcho(0); + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(1); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), 1); + EXPECT_EQ(response.channel().data().calls_succeeded(), 1); + EXPECT_EQ(response.channel().data().calls_failed(), 0); +} + +TEST_F(ChannelzServerTest, FailedRequestTest) { + ResetStubs(); + ConfigureProxy(1); + SendFailedEcho(0); + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(1); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), 1); + EXPECT_EQ(response.channel().data().calls_succeeded(), 0); + EXPECT_EQ(response.channel().data().calls_failed(), 1); +} + +TEST_F(ChannelzServerTest, ManyRequestsTest) { + ResetStubs(); + ConfigureProxy(1); + // send some RPCs + const int kNumSuccess = 10; + const int kNumFailed = 11; + for (int i = 0; i < kNumSuccess; ++i) { + SendSuccessfulEcho(0); + } + for (int i = 0; i < kNumFailed; ++i) { + SendFailedEcho(0); + } + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(1); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), + kNumSuccess + kNumFailed); + EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); + EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); +} + +TEST_F(ChannelzServerTest, ManyChannels) { + ResetStubs(); + const int kNumChannels = 4; + ConfigureProxy(kNumChannels); + GetTopChannelsRequest request; + GetTopChannelsResponse response; + request.set_start_channel_id(0); + ClientContext context; + Status s = channelz_stub_->GetTopChannels(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel_size(), kNumChannels); +} + +TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { + ResetStubs(); + const int kNumChannels = 4; + ConfigureProxy(kNumChannels); + const int kNumSuccess = 10; + const int kNumFailed = 11; + for (int i = 0; i < kNumSuccess; ++i) { + SendSuccessfulEcho(0); + SendSuccessfulEcho(2); + } + for (int i = 0; i < kNumFailed; ++i) { + SendFailedEcho(1); + SendFailedEcho(2); + } + + // the first channel saw only successes + { + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(1); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess); + EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); + EXPECT_EQ(response.channel().data().calls_failed(), 0); + } + + // the second channel saw only failures + { + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(2); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), kNumFailed); + EXPECT_EQ(response.channel().data().calls_succeeded(), 0); + EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); + } + + // the third channel saw both + { + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(3); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), + kNumSuccess + kNumFailed); + EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); + EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); + } + + // the fourth channel saw nothing + { + GetChannelRequest request; + GetChannelResponse response; + request.set_channel_id(4); + ClientContext context; + Status s = channelz_stub_->GetChannel(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.channel().data().calls_started(), 0); + EXPECT_EQ(response.channel().data().calls_succeeded(), 0); + EXPECT_EQ(response.channel().data().calls_failed(), 0); + } +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 8896fc6cae7..c5a73a24698 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -279,9 +279,14 @@ class ClientLbEnd2endTest : public ::testing::Test { void WaitForServer( const std::unique_ptr& stub, - size_t server_idx, const grpc_core::DebugLocation& location) { + size_t server_idx, const grpc_core::DebugLocation& location, + bool ignore_failure = false) { do { - CheckRpcSendOk(stub, location); + if (ignore_failure) { + SendRpc(stub); + } else { + CheckRpcSendOk(stub, location); + } } while (servers_[server_idx]->service_.request_count() == 0); ResetCounters(); } @@ -507,6 +512,37 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { + // Prepare the ports for up servers and down servers. + const int kNumServers = 3; + const int kNumAliveServers = 1; + StartServers(kNumAliveServers); + std::vector alive_ports, dead_ports; + for (size_t i = 0; i < kNumServers; ++i) { + if (i < kNumAliveServers) { + alive_ports.emplace_back(servers_[i]->port_); + } else { + dead_ports.emplace_back(grpc_pick_unused_port_or_die()); + } + } + auto channel = BuildChannel("pick_first"); + auto stub = BuildStub(channel); + // The initial resolution only contains dead ports. There won't be any + // selected subchannel. Re-resolution will return the same result. + SetNextResolution(dead_ports); + gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******"); + for (size_t i = 0; i < 10; ++i) CheckRpcSendFailure(stub); + // Set a re-resolution result that contains reachable ports, so that the + // pick_first LB policy can recover soon. + SetNextResolutionUponError(alive_ports); + gpr_log(GPR_INFO, "****** RE-RESOLUTION SET *******"); + WaitForServer(stub, 0, DEBUG_LOCATION, true /* ignore_failure */); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(servers_[0]->service_.request_count(), 1); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index e7d093c71a4..b958c75fc7c 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -34,11 +34,13 @@ grpc_cc_library( "qps_worker.cc", "server_async.cc", "server_sync.cc", + "qps_server_builder.cc", ], hdrs = [ "client.h", "qps_worker.h", "server.h", + "qps_server_builder.h", ], deps = [ ":histogram", @@ -55,6 +57,10 @@ grpc_cc_library( "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", + "//test/cpp/util:test_config", + ], + external_deps = [ + "gflags", ], ) diff --git a/test/cpp/qps/benchmark_config.cc b/test/cpp/qps/benchmark_config.cc index a4fd9de8206..5fd0f000389 100644 --- a/test/cpp/qps/benchmark_config.cc +++ b/test/cpp/qps/benchmark_config.cc @@ -22,6 +22,8 @@ #include #include +#include "test/cpp/util/test_credentials_provider.h" + DEFINE_bool(enable_log_reporter, true, "Enable reporting of benchmark results through GprLog"); @@ -44,6 +46,10 @@ DEFINE_string(rpc_reporter_server_address, "", DEFINE_bool(enable_rpc_reporter, false, "Enable use of RPC reporter"); +DEFINE_string( + rpc_reporter_credential_type, grpc::testing::kInsecureCredentialsType, + "Credential type for communication to the QPS benchmark report server"); + // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. namespace google {} @@ -65,11 +71,14 @@ static std::shared_ptr InitBenchmarkReporters() { new JsonReporter("JsonReporter", FLAGS_scenario_result_file))); } if (FLAGS_enable_rpc_reporter) { + ChannelArguments channel_args; + std::shared_ptr channel_creds = + testing::GetCredentialsProvider()->GetChannelCredentials( + FLAGS_rpc_reporter_credential_type, &channel_args); GPR_ASSERT(!FLAGS_rpc_reporter_server_address.empty()); composite_reporter->add(std::unique_ptr(new RpcReporter( - "RpcReporter", - grpc::CreateChannel(FLAGS_rpc_reporter_server_address, - grpc::InsecureChannelCredentials())))); + "RpcReporter", grpc::CreateChannel(FLAGS_rpc_reporter_server_address, + channel_creds)))); } return std::shared_ptr(composite_reporter); diff --git a/test/cpp/qps/qps_server_builder.cc b/test/cpp/qps/qps_server_builder.cc new file mode 100644 index 00000000000..5fbc682b756 --- /dev/null +++ b/test/cpp/qps/qps_server_builder.cc @@ -0,0 +1,45 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "qps_server_builder.h" + +using grpc::ServerBuilder; + +namespace grpc { +namespace testing { + +namespace { +std::unique_ptr DefaultCreateQpsServerBuilder() { + return std::unique_ptr(new ServerBuilder()); +} + +std::function()> g_create_qps_server_builder = + DefaultCreateQpsServerBuilder; +} // namespace + +std::unique_ptr CreateQpsServerBuilder() { + return g_create_qps_server_builder(); +} + +void SetCreateQpsServerBuilderFunc( + std::function()> create_qps_server_builder) { + g_create_qps_server_builder = std::move(create_qps_server_builder); +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/qps/qps_server_builder.h b/test/cpp/qps/qps_server_builder.h new file mode 100644 index 00000000000..98f9fa72e97 --- /dev/null +++ b/test/cpp/qps/qps_server_builder.h @@ -0,0 +1,46 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_QPS_SERVER_BUILDER_H +#define GRPC_QPS_SERVER_BUILDER_H + +#include +#include + +#include + +namespace grpc { +namespace testing { + +// CreateQpsServerBuilder creates a new ServerBuilder. +// This uses the "create ServerBuilder" func that was set +// in SetCreateQpsServerBuilderFunc if one has been set, +// otherwise, this defaults to creating a new ServerBuilder +// with only its default constructor. +std::unique_ptr CreateQpsServerBuilder(); + +// SetCreateQpsServerBuilderFunc sets a function to use to create new +// ServerBuilders in "CreateQpsServerBuilder". It can be used to modify options +// that the server is built with. +void SetCreateQpsServerBuilderFunc( + std::function()>); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_QPS_SERVER_BUILDER_H diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index d3f03804743..7ddf3c1cf3b 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -39,6 +39,7 @@ #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" #include "test/cpp/qps/client.h" +#include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" #include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/test_credentials_provider.h" @@ -272,18 +273,18 @@ QpsWorker::QpsWorker(int driver_port, int server_port, impl_.reset(new WorkerServiceImpl(server_port, this)); gpr_atm_rel_store(&done_, static_cast(0)); - ServerBuilder builder; + std::unique_ptr builder = CreateQpsServerBuilder(); if (driver_port >= 0) { char* server_address = nullptr; gpr_join_host_port(&server_address, "::", driver_port); - builder.AddListeningPort( + builder->AddListeningPort( server_address, GetCredentialsProvider()->GetServerCredentials(credential_type)); gpr_free(server_address); } - builder.RegisterService(impl_.get()); + builder->RegisterService(impl_.get()); - server_ = builder.BuildAndStart(); + server_ = builder->BuildAndStart(); } QpsWorker::~QpsWorker() {} diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 1dfef6cfc17..5cd975cf742 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -38,6 +38,7 @@ #include "src/core/lib/surface/completion_queue.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/core/util/test_config.h" +#include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" namespace grpc { @@ -74,19 +75,19 @@ class AsyncQpsServerTest final : public grpc::testing::Server { ResponseType*)> process_rpc) : Server(config) { - ServerBuilder builder; + std::unique_ptr builder = CreateQpsServerBuilder(); auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { char* server_address = nullptr; gpr_join_host_port(&server_address, "::", port_num); - builder.AddListeningPort(server_address, - Server::CreateServerCredentials(config)); + builder->AddListeningPort(server_address, + Server::CreateServerCredentials(config)); gpr_free(server_address); } - register_service(&builder, &async_service_); + register_service(builder.get(), &async_service_); int num_threads = config.async_server_threads(); if (num_threads <= 0) { // dynamic sizing @@ -97,15 +98,15 @@ class AsyncQpsServerTest final : public grpc::testing::Server { int tpc = std::max(1, config.threads_per_cq()); // 1 if unspecified int num_cqs = (num_threads + tpc - 1) / tpc; // ceiling operator for (int i = 0; i < num_cqs; i++) { - srv_cqs_.emplace_back(builder.AddCompletionQueue()); + srv_cqs_.emplace_back(builder->AddCompletionQueue()); } for (int i = 0; i < num_threads; i++) { cq_.emplace_back(i % srv_cqs_.size()); } - ApplyConfigToBuilder(config, &builder); + ApplyConfigToBuilder(config, builder.get()); - server_ = builder.BuildAndStart(); + server_ = builder->BuildAndStart(); auto process_rpc_bound = std::bind(process_rpc, config.payload_config(), std::placeholders::_1, diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index b8facf9b569..2e63f5ec867 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -27,6 +27,7 @@ #include "src/core/lib/gpr/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" +#include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" #include "test/cpp/qps/usage_timer.h" @@ -154,23 +155,23 @@ class BenchmarkServiceImpl final : public BenchmarkService::Service { class SynchronousServer final : public grpc::testing::Server { public: explicit SynchronousServer(const ServerConfig& config) : Server(config) { - ServerBuilder builder; + std::unique_ptr builder = CreateQpsServerBuilder(); auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { char* server_address = nullptr; gpr_join_host_port(&server_address, "::", port_num); - builder.AddListeningPort(server_address, - Server::CreateServerCredentials(config)); + builder->AddListeningPort(server_address, + Server::CreateServerCredentials(config)); gpr_free(server_address); } - ApplyConfigToBuilder(config, &builder); + ApplyConfigToBuilder(config, builder.get()); - builder.RegisterService(&service_); + builder->RegisterService(&service_); - impl_ = builder.BuildAndStart(); + impl_ = builder->BuildAndStart(); } std::shared_ptr InProcessChannel( diff --git a/test/cpp/server/load_reporter/load_reporter_test.cc b/test/cpp/server/load_reporter/load_reporter_test.cc index 719c3a67d96..0d56cdf431d 100644 --- a/test/cpp/server/load_reporter/load_reporter_test.cc +++ b/test/cpp/server/load_reporter/load_reporter_test.cc @@ -172,9 +172,9 @@ class LbFeedbackTest : public LoadReporterTest { // TODO(juanlishen): The error is big because we use sleep(). It should be // much smaller when we use fake clock. ASSERT_THAT(static_cast(lb_feedback.calls_per_second()), - DoubleNear(expected_qps, expected_qps / 50)); + DoubleNear(expected_qps, expected_qps * 0.05)); ASSERT_THAT(static_cast(lb_feedback.errors_per_second()), - DoubleNear(expected_eps, expected_eps / 50)); + DoubleNear(expected_eps, expected_eps * 0.05)); gpr_log(GPR_INFO, "Verified LB feedback matches the samples of index [%lu, %lu).", start, start + count); diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 29fc4fdaf3c..02cd87a7b9b 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -42,7 +42,7 @@ platform( } properties: { name: "gceMachineType" # Small machines for majority of tests. - value: "n1-standard-1" + value: "n1-highmem-2" } properties: { name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN. diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index ae249e73861..ccb69a8ebcb 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.14.0.dev0' +VERSION = '1.15.0.dev0' diff --git a/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile b/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile index 77b6acfb160..be96f131f92 100644 --- a/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile +++ b/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile @@ -12,9 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Docker file for building gRPC artifacts. +# Docker file for building gRPC artifacts for Android. -# Recent enough cmake (>=3.9) needed by Android SDK FROM debian:sid RUN apt-get update && apt-get install -y debian-keyring && apt-key update @@ -47,20 +46,26 @@ RUN apt-get update && apt-key update && apt-get install -y \ wget \ zip && apt-get clean -# Cmake for cross-compilation -RUN apt-get update && apt-get install -y cmake golang && apt-get clean +# golang needed to build BoringSSL with cmake +RUN apt-get update && apt-get install -y golang && apt-get clean -################## -# Android NDK +# Java required by Android SDK +RUN apt-get update && apt-get -y install openjdk-8-jdk && apt-get clean -# Download and install Android NDK -RUN wget -q https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip -O android_ndk.zip \ - && unzip -q android_ndk.zip \ - && rm android_ndk.zip \ - && mv ./android-ndk-r16b /opt -ENV ANDROID_NDK_PATH /opt/android-ndk-r16b +# Install Android SDK +ENV ANDROID_SDK_VERSION 4333796 +RUN mkdir -p /opt/android-sdk && cd /opt/android-sdk && \ + wget -q https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \ + unzip -q sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \ + rm sdk-tools-linux-${ANDROID_SDK_VERSION}.zip +ENV ANDROID_SDK_PATH /opt/android-sdk -RUN apt-get update && apt-get install -y libpthread-stubs0-dev && apt-get clean +# Install Android NDK and cmake using sdkmanager +RUN mkdir -p ~/.android && touch ~/.android/repositories.cfg +RUN yes | ${ANDROID_SDK_PATH}/tools/bin/sdkmanager --licenses # accept all licenses +RUN ${ANDROID_SDK_PATH}/tools/bin/sdkmanager ndk-bundle 'cmake;3.6.4111459' +ENV ANDROID_NDK_PATH ${ANDROID_SDK_PATH}/ndk-bundle +ENV ANDROID_SDK_CMAKE ${ANDROID_SDK_PATH}/cmake/3.6.4111459/bin/cmake RUN mkdir /var/local/jenkins diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 322ab5eb983..2f06bda0168 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.14.0-dev +PROJECT_NUMBER = 1.15.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ba322a90a54..a46ebe61976 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.14.0-dev +PROJECT_NUMBER = 1.15.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg b/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg new file mode 100644 index 00000000000..619e3ea3a97 --- /dev/null +++ b/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg @@ -0,0 +1,26 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_build_artifacts_extra.sh" +timeout_mins: 240 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + regex: "github/grpc/reports/**" + regex: "github/grpc/artifacts/**" + } +} diff --git a/tools/internal_ci/linux/grpc_publish_packages.sh b/tools/internal_ci/linux/grpc_publish_packages.sh old mode 100644 new mode 100755 index 89da36987e0..ef943db7e15 --- a/tools/internal_ci/linux/grpc_publish_packages.sh +++ b/tools/internal_ci/linux/grpc_publish_packages.sh @@ -17,94 +17,218 @@ set -ex shopt -s nullglob -export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json - -GCS_ROOT=gs://packages.grpc.io -MANIFEST_FILE=index.xml -ARCHIVE_UUID=${KOKORO_BUILD_ID:-$(uuidgen)} -GIT_BRANCH_NAME=master #${KOKORO_GITHUB_COMMIT:-master} -GIT_COMMIT=${KOKORO_GIT_COMMIT:-unknown} -ARCHIVE_TIMESTAMP=$(date -Iseconds) -TARGET_DIR=$(mktemp -d grpc_publish_packages.sh.XXXX) -YEAR_MONTH_PREFIX=$(date "+%Y/%m") -YEAR_PREFIX=${YEAR_MONTH_PREFIX%%/*} -UPLOAD_ROOT=$TARGET_DIR/$YEAR_PREFIX -RELATIVE_PATH=$YEAR_MONTH_PREFIX/$ARCHIVE_UUID -BUILD_ROOT=$TARGET_DIR/$RELATIVE_PATH - -LINUX_PACKAGES=$KOKORO_GFILE_DIR/github/grpc/artifacts -WINDOWS_PACKAGES=$KOKORO_GFILE_DIR/github/grpc/artifacts -# TODO(mmx): enable linux_extra -# LINUX_EXTRA_PACKAGES=$KOKORO_GFILE_DIR/github/grpc/artifacts - -PYTHON_PACKAGES=( - "$LINUX_PACKAGES"/grpcio-[0-9]*.whl - "$LINUX_PACKAGES"/grpcio-[0-9]*.tar.gz - "$LINUX_PACKAGES"/grpcio_tools-[0-9]*.whl - "$LINUX_PACKAGES"/grpcio-tools-[0-9]*.tar.gz - "$LINUX_PACKAGES"/grpcio-health-checking-[0-9]*.tar.gz - "$LINUX_PACKAGES"/grpcio-reflection-[0-9]*.tar.gz - "$LINUX_PACKAGES"/grpcio-testing-[0-9]*.tar.gz - #"$LINUX_EXTRA_PACKAGES"/grpcio-[0-9]*.whl - #"$LINUX_EXTRA_PACKAGES"/grpcio_tools-[0-9]*.whl +cd "$(dirname "$0")/../../.." + +GRPC_VERSION=$(grep -e "^ *version: " build.yaml | head -n 1 | sed 's/.*: //') + +INPUT_ARTIFACTS=$KOKORO_GFILE_DIR/github/grpc/artifacts +INDEX_FILENAME=index.xml + +BUILD_ID=${KOKORO_BUILD_ID:-$(uuidgen)} +BUILD_BRANCH_NAME=master +BUILD_GIT_COMMIT=${KOKORO_GIT_COMMIT:-unknown} +BUILD_TIMESTAMP=$(date -Iseconds) +BUILD_RELPATH=$(date "+%Y/%m")/$BUILD_GIT_COMMIT-$BUILD_ID/ + +GCS_ROOT=gs://packages.grpc.io/ +GCS_ARCHIVE_PREFIX=archive/ +GCS_ARCHIVE_ROOT=$GCS_ROOT$GCS_ARCHIVE_PREFIX +GCS_INDEX=$GCS_ROOT$INDEX_FILENAME + +LOCAL_STAGING_TEMPDIR=$(mktemp -d) +LOCAL_BUILD_ROOT=$LOCAL_STAGING_TEMPDIR/$BUILD_RELPATH +LOCAL_BUILD_INDEX=$LOCAL_BUILD_ROOT$INDEX_FILENAME + +mkdir -p "$LOCAL_BUILD_ROOT" + +find "$INPUT_ARTIFACTS" -type f + +# protoc Plugins +PROTOC_PLUGINS_ZIPPED_PACKAGES=$(mktemp -d) +for zip_dir in protoc_windows_{x86,x64} +do + zip -jr "$PROTOC_PLUGINS_ZIPPED_PACKAGES/grpc-$zip_dir-$GRPC_VERSION.zip" "$INPUT_ARTIFACTS/$zip_dir/"* +done +for tar_dir in protoc_{linux,macos}_{x86,x64} +do + chmod +x "$INPUT_ARTIFACTS/$tar_dir"/* + tar -cvzf "$PROTOC_PLUGINS_ZIPPED_PACKAGES/grpc-$tar_dir-$GRPC_VERSION.tar.gz" -C "$INPUT_ARTIFACTS/$tar_dir" . +done + +PROTOC_PACKAGES=( + "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_windows_{x86,x64}-"$GRPC_VERSION.zip" + "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_{linux,macos}_{x86,x64}-"$GRPC_VERSION.tar.gz" ) -PHP_PACKAGES=( - "$LINUX_PACKAGES"/grpc-[0-9]*.tgz +# C# +UNZIPPED_CSHARP_PACKAGES=$(mktemp -d) +unzip "$INPUT_ARTIFACTS/csharp_nugets_windows_dotnetcli.zip" -d "$UNZIPPED_CSHARP_PACKAGES" +CSHARP_PACKAGES=( + "$UNZIPPED_CSHARP_PACKAGES"/* ) -RUBY_PACKAGES=( - "$LINUX_PACKAGES"/grpc-[0-9]*.gem - "$LINUX_PACKAGES"/grpc-tools-[0-9]*.gem +# Python +PYTHON_GRPCIO_PACKAGES=( + "$INPUT_ARTIFACTS"/grpcio-[0-9]*.tar.gz + "$INPUT_ARTIFACTS"/grpcio-[0-9]*.whl + "$INPUT_ARTIFACTS"/python_linux_extra_arm*/grpcio-[0-9]*.whl +) +PYTHON_GRPCIO_TOOLS_PACKAGES=( + "$INPUT_ARTIFACTS"/grpcio-tools-[0-9]*.tar.gz + "$INPUT_ARTIFACTS"/grpcio_tools-[0-9]*.whl + "$INPUT_ARTIFACTS"/python_linux_extra_arm*/grpcio_tools-[0-9]*.whl +) +PYTHON_GRPCIO_HEALTH_CHECKING_PACKAGES=( + "$INPUT_ARTIFACTS"/grpcio-health-checking-[0-9]*.tar.gz +) +PYTHON_GRPCIO_REFLECTION_PACKAGES=( + "$INPUT_ARTIFACTS"/grpcio-reflection-[0-9]*.tar.gz +) +PYTHON_GRPCIO_TESTING_PACKAGES=( + "$INPUT_ARTIFACTS"/grpcio-testing-[0-9]*.tar.gz ) -CSHARP_PACKAGES=( - "$WINDOWS_PACKAGES"/csharp_nugets_windows_dotnetcli.zip +# PHP +PHP_PACKAGES=( + "$INPUT_ARTIFACTS"/grpc-[0-9]*.tgz +) + +# Ruby +RUBY_PACKAGES=( + "$INPUT_ARTIFACTS"/grpc-[0-9]*.gem + "$INPUT_ARTIFACTS"/grpc-tools-[0-9]*.gem ) function add_to_manifest() { - local xml_type=$1 - local xml_name - xml_name=$(basename "$2") - local xml_sha256 - xml_sha256=$(openssl sha256 -r "$2" | cut -d " " -f 1) - cp "$2" "$BUILD_ROOT" - echo "" + local artifact_type=$1 + local artifact_file=$2 + local artifact_prefix=$3 + local artifact_name + artifact_name=$(basename "$artifact_file") + local artifact_size + artifact_size=$(stat -c%s "$artifact_file") + local artifact_sha256 + artifact_sha256=$(openssl sha256 -r "$artifact_file" | cut -d " " -f 1) + local artifact_target=$LOCAL_BUILD_ROOT/$artifact_type/$artifact_prefix + mkdir -p "$artifact_target" + cp "$artifact_file" "$artifact_target" + cat < +EOF } -mkdir -p "$BUILD_ROOT" - { cat < - + + + + gRPC + https://github.com/grpc/grpc + $BUILD_BRANCH_NAME + $BUILD_GIT_COMMIT + + EOF - echo "" - echo "" - echo "$GIT_BRANCH_NAME" - echo "$GIT_COMMIT" - echo "" - for pkg in "${PYTHON_PACKAGES[@]}"; do add_to_manifest python "$pkg"; done + for pkg in "${PROTOC_PACKAGES[@]}"; do add_to_manifest protoc "$pkg"; done for pkg in "${CSHARP_PACKAGES[@]}"; do add_to_manifest csharp "$pkg"; done for pkg in "${PHP_PACKAGES[@]}"; do add_to_manifest php "$pkg"; done + for pkg in "${PYTHON_GRPCIO_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio/; done + for pkg in "${PYTHON_GRPCIO_TOOLS_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-tools/; done + for pkg in "${PYTHON_GRPCIO_HEALTH_CHECKING_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-health-checking/; done + for pkg in "${PYTHON_GRPCIO_REFLECTION_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-reflection/; done + for pkg in "${PYTHON_GRPCIO_TESTING_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-testing/; done for pkg in "${RUBY_PACKAGES[@]}"; do add_to_manifest ruby "$pkg"; done - echo "" -}> "$BUILD_ROOT/$MANIFEST_FILE" + cat < + +EOF +}> "$LOCAL_BUILD_INDEX" + +LOCAL_BUILD_INDEX_SIZE=$(stat -c%s "$LOCAL_BUILD_INDEX") +LOCAL_BUILD_INDEX_SHA256=$(openssl sha256 -r "$LOCAL_BUILD_INDEX" | cut -d " " -f 1) -BUILD_XML_SHA=$(openssl sha256 -r "$BUILD_ROOT/$MANIFEST_FILE" | cut -d " " -f 1) +OLD_INDEX=$(mktemp) +NEW_INDEX=$(mktemp) -PREV_HOME=$(mktemp old-XXXXX-$MANIFEST_FILE) -NEW_HOME=$(mktemp new-XXXXX-$MANIFEST_FILE) -gsutil cp "$GCS_ROOT/$MANIFEST_FILE" "$PREV_HOME" +# Download the current /index.xml into $OLD_INDEX +gsutil cp "$GCS_INDEX" "$OLD_INDEX" { - head --lines=4 "$PREV_HOME" - echo "" - tail --lines=+5 "$PREV_HOME" -}> "$NEW_HOME" + # we want to add an entry as the first child under tag + # we can get by without a real XML parser by rewriting the header, + # injecting our new tag, and then dumping the rest of the file as is. + cat < + + + + +EOF + tail --lines=+5 "$OLD_INDEX" +}> "$NEW_INDEX" -gsutil -m cp -r "$UPLOAD_ROOT" "$GCS_ROOT/archive" -gsutil -h "Content-Type:application/xml" cp "$NEW_HOME" "$GCS_ROOT/$MANIFEST_FILE" +function generate_directory_index() +{ + local target_dir=$1 + local current_directory_name + current_directory_name=$(basename "$target_dir") + cat < + + + + Index of $current_directory_name - packages.grpc.io + + + +

Index of $current_directory_name

+
    +
  • .
  • +
  • ..
  • +EOF + +( + cd "$target_dir" + find * -maxdepth 0 -type d -print | sort | while read -r line + do + echo "
  • $line/
  • " + done + find * -maxdepth 0 -type f -print | sort | while read -r line + do + echo "
  • $line
  • " + done +) + +cat < + + +EOF +} + +# Upload the current build artifacts +gsutil -m cp -r "$LOCAL_STAGING_TEMPDIR/${BUILD_RELPATH%%/*}" "$GCS_ARCHIVE_ROOT" +# Upload directory indicies for subdirectories +( + cd "$LOCAL_BUILD_ROOT" + find * -type d | while read -r directory + do + generate_directory_index "$directory" | gsutil -h 'Content-Type:text/html' cp - "$GCS_ARCHIVE_ROOT$BUILD_RELPATH$directory/$INDEX_FILENAME" + done +) +# Upload the new /index.xml +gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX" diff --git a/tools/package_hosting/404.html b/tools/package_hosting/404.html new file mode 100644 index 00000000000..44d986c4b06 --- /dev/null +++ b/tools/package_hosting/404.html @@ -0,0 +1 @@ +404 Not Found diff --git a/tools/package_hosting/build-201807.xsl b/tools/package_hosting/build-201807.xsl new file mode 100644 index 00000000000..69a190446fa --- /dev/null +++ b/tools/package_hosting/build-201807.xsl @@ -0,0 +1,114 @@ + + + + + + + Artifacts for gRPC Build <xsl:value-of select="@id"/> + + + + + + + + + + + + + + + +
    + Artifacts for gRPC Build +
    +
    +
    + Build: + [invocation]
    + Timestamp: +
    + Branch: + + +
    + Commit: + +
    +
    + +
    +
    + +

    gRPC is a Cloud Native Computing Foundation project. Privacy Policy.

    +

    + Copyright ©  The gRPC Authors

    +
    +
    +
    + + +
    + + +

    gRPC protoc Plugins

    + + + + +
    + +

    C#

    + + + + +
    + +

    PHP

    + + + + +
    + +

    Python

    + + + + + +
    + +

    Ruby

    + + + + +
    + +
    + + + + + + + + + + + + +
    diff --git a/tools/package_hosting/dirindex.css b/tools/package_hosting/dirindex.css new file mode 100644 index 00000000000..6c4b04ea323 --- /dev/null +++ b/tools/package_hosting/dirindex.css @@ -0,0 +1,16 @@ +ul { + list-style-type: none; +} +a{ + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +ul li a { + font-family: 'SF Mono', 'Menlo', 'Monaco', 'Consolas', 'Courier New', Courier, monospace +} +h1 { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif +} + diff --git a/tools/package_hosting/home.xsl b/tools/package_hosting/home.xsl new file mode 100644 index 00000000000..3f79303b1b7 --- /dev/null +++ b/tools/package_hosting/home.xsl @@ -0,0 +1,86 @@ + + + + + + + gRPC Packages + + + + + + + + + + + + + + +
    + gRPC Packages +
    +
    + + +
    +
    +

    gRPC is a Cloud Native Computing Foundation project. Privacy Policy.

    +

    Copyright © 2018 The gRPC Authors

    +
    + + +
    + + +

    Official gRPC Releases

    +

    Commits corresponding to official gRPC release points and release candidates are tagged on GitHub.

    +

    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.

    +

    For instructions on how to use the language-specific gRPC runtime in your project, please refer to the following:

    + +
    + + +

    Daily Builds of master Branch

    +

    gRPC packages are built on a daily basis at the HEAD of the master branch and are archived here.

    +

    + The current document (view source) is an XML feed pointing to the packages as they get built and uploaded. + You can subscribe to this feed and fetch, deploy, and test the precompiled packages with your continuous integration infrastructure. +

    +

    For stable release packages, please consult the above section and the common package manager for your language.

    + + + + + + + + + +
    TimestampCommitBuild ID
    +
    + + + + + + + + + +
    diff --git a/tools/package_hosting/style.css b/tools/package_hosting/style.css new file mode 100644 index 00000000000..dbd26d50cf5 --- /dev/null +++ b/tools/package_hosting/style.css @@ -0,0 +1,76 @@ +html, body +{ + margin: 0; + font-family: sans-serif; +} + +a, a:visited, a:link, a:active { + color: #2da6b0; + text-decoration: none; +} + +a:hover { + color: #2da6b0; + text-decoration: underline; +} + +#topbar { + background-color: #2da6b0; + height: 60px; + margin:auto; +} + +#topbar .title { + position: relative; + top: 24px; + left: 24px; + color: white; + font-family: sans-serif; + font-weight: bold; +} + +#main { + max-width:1100px; + margin:auto; +} + +#main h2 { + text-align: left; +} + +#main table { + width:100%; + border-collapse: collapse; + font-size: small; + font-family: 'SF Mono', 'Menlo', 'Monaco', 'Courier New', Courier, monospace; +} +#main table tr td { + border: solid black 1px; + padding: 5px; +} + +#main table tr td.hash { + text-align: right; + border-left: none; + font-size: x-small; +} + +#main table tr td.name { + text-align: left; + border-right: none; +} + +p.description +{ + font-size: smaller; +} + +#metadata { + margin-top: 15px; + padding: 15px; + font-family: 'SF Mono', 'Menlo', 'Monaco', 'Courier New', Courier, monospace; +} + +#metadata span.fieldname { + font-family: sans-serif; +} \ No newline at end of file diff --git a/tools/package_hosting/upload_web_assets.sh b/tools/package_hosting/upload_web_assets.sh new file mode 100755 index 00000000000..dcf258e38eb --- /dev/null +++ b/tools/package_hosting/upload_web_assets.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +cd "$(dirname "$0")" + +GCS_WEB_ASSETS=gs://packages.grpc.io/web-assets/ + +WEB_ASSETS=( + 404.html + build-201807.xsl + dirindex.css + home.xsl + style.css +) + +gsutil -m cp "${WEB_ASSETS[@]}" "$GCS_WEB_ASSETS" diff --git a/tools/profiling/ios_bin/binary_size.py b/tools/profiling/ios_bin/binary_size.py index cde09023f20..b07adb57345 100755 --- a/tools/profiling/ios_bin/binary_size.py +++ b/tools/profiling/ios_bin/binary_size.py @@ -86,7 +86,7 @@ def build(where, frameworks): 'src/objective-c/examples/Sample/Build-%s' % where) -text = '' +text = 'Objective-C binary sizes\n' for frameworks in [False, True]: build('new', frameworks) new_size = get_size('new', frameworks) diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py index edde3eae28d..01323b53266 100644 --- a/tools/run_tests/artifacts/artifact_targets.py +++ b/tools/run_tests/artifacts/artifact_targets.py @@ -212,11 +212,15 @@ class RubyArtifact: class CSharpExtArtifact: """Builds C# native extension library""" - def __init__(self, platform, arch): + def __init__(self, platform, arch, arch_abi=None): self.name = 'csharp_ext_%s_%s' % (platform, arch) self.platform = platform self.arch = arch + self.arch_abi = arch_abi self.labels = ['artifact', 'csharp', platform, arch] + if arch_abi: + self.name += '_%s' % arch_abi + self.labels.append(arch_abi) def pre_build_jobspecs(self): return [] @@ -227,7 +231,14 @@ class CSharpExtArtifact: self.name, 'tools/dockerfile/grpc_artifact_android_ndk', 'tools/run_tests/artifacts/build_artifact_csharp_android.sh', - environ={}) + environ={ + 'ANDROID_ABI': self.arch_abi + }) + elif self.arch == 'ios': + return create_jobspec( + self.name, + ['tools/run_tests/artifacts/build_artifact_csharp_ios.sh'], + use_workspace=True) elif self.platform == 'windows': cmake_arch_option = 'Win32' if self.arch == 'x86' else self.arch return create_jobspec( @@ -348,7 +359,10 @@ def targets(): for Cls in (CSharpExtArtifact, ProtocArtifact) for platform in ('linux', 'macos', 'windows') for arch in ('x86', 'x64') ] + [ - CSharpExtArtifact('linux', 'android'), + CSharpExtArtifact('linux', 'android', arch_abi='arm64-v8a'), + CSharpExtArtifact('linux', 'android', arch_abi='armeabi-v7a'), + CSharpExtArtifact('linux', 'android', arch_abi='x86'), + CSharpExtArtifact('macos', 'ios'), PythonArtifact('linux', 'x86', 'cp27-cp27m'), PythonArtifact('linux', 'x86', 'cp27-cp27mu'), PythonArtifact('linux', 'x86', 'cp34-cp34m'), diff --git a/tools/run_tests/artifacts/build_artifact_csharp_android.sh b/tools/run_tests/artifacts/build_artifact_csharp_android.sh index ba598e76a4b..067eb30edcf 100755 --- a/tools/run_tests/artifacts/build_artifact_csharp_android.sh +++ b/tools/run_tests/artifacts/build_artifact_csharp_android.sh @@ -17,6 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." +# ANDROID_ABI is set by the job definition in artifact_targets.py src/csharp/experimental/build_native_ext_for_android.sh mkdir -p "${ARTIFACTS_OUT}" diff --git a/tools/run_tests/artifacts/build_artifact_csharp_ios.sh b/tools/run_tests/artifacts/build_artifact_csharp_ios.sh new file mode 100755 index 00000000000..c902a45db7d --- /dev/null +++ b/tools/run_tests/artifacts/build_artifact_csharp_ios.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +cd "$(dirname "$0")/../../.." + +src/csharp/experimental/build_native_ext_for_ios.sh + +mkdir -p "${ARTIFACTS_OUT}" +cp libs/ios/libgrpc_csharp_ext.a libs/ios/libgrpc.a "${ARTIFACTS_OUT}" diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7953fa37723..072402b2cf6 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3124,10 +3124,10 @@ "gpr_test_util", "grpc", "grpc++", - "grpc++_channelz_proto", "grpc++_test", "grpc++_test_util", - "grpc_test_util" + "grpc_test_util", + "grpcpp_channelz_proto" ], "headers": [], "is_filegroup": false, @@ -3165,10 +3165,31 @@ "gpr_test_util", "grpc", "grpc++", - "grpc++_channelz_proto", + "grpc++_test_util", + "grpc_test_util", + "grpcpp_channelz", + "grpcpp_channelz_proto" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "channelz_service_test", + "src": [ + "test/cpp/end2end/channelz_service_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", "grpc++_test", "grpc++_test_util", - "grpc_test_util" + "grpc_test_util", + "grpcpp_channelz_proto" ], "headers": [], "is_filegroup": false, @@ -7528,6 +7549,28 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "grpc", + "grpc++", + "grpcpp_channelz_proto" + ], + "headers": [ + "include/grpcpp/ext/channelz_service_plugin.h", + "src/cpp/server/channelz/channelz_service.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "grpcpp_channelz", + "src": [ + "include/grpcpp/ext/channelz_service_plugin.h", + "src/cpp/server/channelz/channelz_service.cc", + "src/cpp/server/channelz/channelz_service.h", + "src/cpp/server/channelz/channelz_service_plugin.cc" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "grpc", @@ -7718,6 +7761,7 @@ "test/cpp/qps/histogram.h", "test/cpp/qps/interarrival.h", "test/cpp/qps/parse_json.h", + "test/cpp/qps/qps_server_builder.h", "test/cpp/qps/qps_worker.h", "test/cpp/qps/report.h", "test/cpp/qps/server.h", @@ -7739,6 +7783,8 @@ "test/cpp/qps/interarrival.h", "test/cpp/qps/parse_json.cc", "test/cpp/qps/parse_json.h", + "test/cpp/qps/qps_server_builder.cc", + "test/cpp/qps/qps_server_builder.h", "test/cpp/qps/qps_worker.cc", "test/cpp/qps/qps_worker.h", "test/cpp/qps/report.cc", @@ -10888,20 +10934,6 @@ "third_party": false, "type": "filegroup" }, - { - "deps": [], - "headers": [ - "src/proto/grpc/channelz/channelz.grpc.pb.h", - "src/proto/grpc/channelz/channelz.pb.h", - "src/proto/grpc/channelz/channelz_mock.grpc.pb.h" - ], - "is_filegroup": true, - "language": "c++", - "name": "grpc++_channelz_proto", - "src": [], - "third_party": false, - "type": "filegroup" - }, { "deps": [ "grpc_codegen" @@ -11377,5 +11409,19 @@ ], "third_party": false, "type": "filegroup" + }, + { + "deps": [], + "headers": [ + "src/proto/grpc/channelz/channelz.grpc.pb.h", + "src/proto/grpc/channelz/channelz.pb.h", + "src/proto/grpc/channelz/channelz_mock.grpc.pb.h" + ], + "is_filegroup": true, + "language": "c++", + "name": "grpcpp_channelz_proto", + "src": [], + "third_party": false, + "type": "filegroup" } ] diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 5c556a2f52f..a5439a5db13 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3755,6 +3755,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": "channelz_service_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false,