Merge branch 'master' into handshaker

pull/10925/head
jiangtaoli2016 8 years ago
commit 18836bec50
  1. 20
      BUILD
  2. 59
      CMakeLists.txt
  3. 62
      Makefile
  4. 2
      Rakefile
  5. 40
      binding.gyp
  6. 40
      build.yaml
  7. 2
      config.m4
  8. 6
      gRPC-Core.podspec
  9. 4
      grpc.gemspec
  10. 37
      include/grpc++/impl/codegen/call.h
  11. 3
      include/grpc/impl/codegen/grpc_types.h
  12. 2
      include/grpc/impl/codegen/port_platform.h
  13. 3
      package.json
  14. 4
      package.xml
  15. 6
      setup.py
  16. 6
      src/compiler/cpp_generator.cc
  17. 12
      src/compiler/python_generator.cc
  18. 120
      src/core/ext/filters/client_channel/client_channel.c
  19. 3
      src/core/ext/filters/client_channel/lb_policy.c
  20. 11
      src/core/ext/filters/client_channel/lb_policy.h
  21. 153
      src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
  22. 45
      src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
  23. 310
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
  24. 133
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
  25. 65
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
  26. 50
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
  27. 6
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
  28. 3
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
  29. 3
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
  30. 2
      src/core/ext/filters/client_channel/subchannel.c
  31. 1
      src/core/ext/filters/client_channel/subchannel.h
  32. 4
      src/core/ext/transport/cronet/transport/cronet_transport.c
  33. 3
      src/core/lib/channel/context.h
  34. 2
      src/core/lib/http/httpcli.c
  35. 1
      src/core/lib/iomgr/port.h
  36. 8
      src/core/lib/support/cpu_linux.c
  37. 4
      src/core/lib/support/wrap_memcpy.c
  38. 3
      src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
  39. 5
      src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
  40. 3
      src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
  41. 1
      src/node/ext/call.cc
  42. 1
      src/node/ext/channel.cc
  43. 4
      src/node/ext/completion_queue.cc
  44. 86
      src/node/ext/completion_queue_async_worker.h
  45. 180
      src/node/ext/completion_queue_threadpool.cc
  46. 5
      src/node/ext/node_grpc.cc
  47. 59
      src/node/ext/server.cc
  48. 120
      src/node/ext/server_uv.cc
  49. 15
      src/proto/grpc/lb/v1/BUILD
  50. 11
      src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
  51. 22
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  52. 2
      src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
  53. 2
      src/python/grpcio/grpc_core_dependencies.py
  54. 1
      src/python/grpcio_health_checking/setup.py
  55. 37
      templates/binding.gyp.template
  56. 3
      templates/package.json.template
  57. 45
      test/core/end2end/cq_verifier.c
  58. 3
      test/core/end2end/fake_resolver.c
  59. 3
      test/core/end2end/fake_resolver.h
  60. 4
      test/core/slice/slice_buffer_test.c
  61. 4
      test/cpp/client/credentials_test.cc
  62. 6
      test/cpp/codegen/compiler_test_golden
  63. 23
      test/cpp/end2end/BUILD
  64. 639
      test/cpp/end2end/grpclb_end2end_test.cc
  65. 2
      test/cpp/thread_manager/thread_manager_test.cc
  66. 2
      test/cpp/util/cli_call.cc
  67. 10
      third_party/cares/ares_build.h
  68. 4
      tools/doxygen/Doxyfile.core.internal
  69. 41
      tools/internal_ci/linux/grpc_fuzzer_api.sh
  70. 39
      tools/internal_ci/linux/grpc_fuzzer_client.cfg
  71. 41
      tools/internal_ci/linux/grpc_fuzzer_client.sh
  72. 39
      tools/internal_ci/linux/grpc_fuzzer_hpack_parser.cfg
  73. 41
      tools/internal_ci/linux/grpc_fuzzer_hpack_parser.sh
  74. 39
      tools/internal_ci/linux/grpc_fuzzer_http_request.cfg
  75. 41
      tools/internal_ci/linux/grpc_fuzzer_http_request.sh
  76. 39
      tools/internal_ci/linux/grpc_fuzzer_json.cfg
  77. 39
      tools/internal_ci/linux/grpc_fuzzer_nanopb_response.cfg
  78. 40
      tools/internal_ci/linux/grpc_fuzzer_nanopb_response.sh
  79. 39
      tools/internal_ci/linux/grpc_fuzzer_server.cfg
  80. 41
      tools/internal_ci/linux/grpc_fuzzer_server.sh
  81. 39
      tools/internal_ci/linux/grpc_fuzzer_uri.cfg
  82. 12
      tools/internal_ci/linux/grpc_master.sh
  83. 2
      tools/internal_ci/linux/grpc_portability.sh
  84. 2
      tools/internal_ci/linux/grpc_portability_build_only.sh
  85. 2
      tools/internal_ci/linux/sanitizer/grpc_c_asan.sh
  86. 2
      tools/internal_ci/linux/sanitizer/grpc_c_msan.sh
  87. 2
      tools/internal_ci/linux/sanitizer/grpc_c_tsan.sh
  88. 2
      tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
  89. 2
      tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh
  90. 6
      tools/internal_ci/macos/grpc_master.cfg
  91. 11
      tools/internal_ci/macos/grpc_master.sh
  92. 2
      tools/internal_ci/windows/grpc_master.bat
  93. 2
      tools/internal_ci/windows/grpc_portability_master.bat
  94. 2
      tools/run_tests/README.md
  95. 2
      tools/run_tests/artifacts/build_artifact_node.sh
  96. 56
      tools/run_tests/generated/sources_and_headers.json
  97. 22
      tools/run_tests/generated/tests.json
  98. 4
      tools/run_tests/helper_scripts/build_node.sh
  99. 5
      tools/run_tests/helper_scripts/pre_build_cmake.bat
  100. 6
      tools/run_tests/helper_scripts/pre_build_csharp.bat
  101. Some files were not shown because too many files have changed in this diff Show More

20
BUILD

@ -829,14 +829,18 @@ grpc_cc_library(
grpc_cc_library( grpc_cc_library(
name = "grpc_lb_policy_grpclb", name = "grpc_lb_policy_grpclb",
srcs = [ srcs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
], ],
hdrs = [ hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
], ],
@ -853,14 +857,18 @@ grpc_cc_library(
grpc_cc_library( grpc_cc_library(
name = "grpc_lb_policy_grpclb_secure", name = "grpc_lb_policy_grpclb_secure",
srcs = [ srcs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
], ],
hdrs = [ hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
], ],
@ -1403,18 +1411,6 @@ grpc_cc_library(
], ],
) )
grpc_cc_library(
name = "thrift_util",
language = "c++",
public_hdrs = [
"include/grpc++/impl/codegen/thrift_serializer.h",
"include/grpc++/impl/codegen/thrift_utils.h",
],
deps = [
"grpc++_codegen_base",
],
)
grpc_cc_library( grpc_cc_library(
name = "grpc++_reflection", name = "grpc++_reflection",
srcs = [ srcs = [

@ -676,6 +676,7 @@ add_dependencies(buildtests_cxx golden_file_test)
add_dependencies(buildtests_cxx grpc_cli) add_dependencies(buildtests_cxx grpc_cli)
add_dependencies(buildtests_cxx grpc_tool_test) add_dependencies(buildtests_cxx grpc_tool_test)
add_dependencies(buildtests_cxx grpclb_api_test) add_dependencies(buildtests_cxx grpclb_api_test)
add_dependencies(buildtests_cxx grpclb_end2end_test)
add_dependencies(buildtests_cxx grpclb_test) add_dependencies(buildtests_cxx grpclb_test)
add_dependencies(buildtests_cxx health_service_end2end_test) add_dependencies(buildtests_cxx health_service_end2end_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -1120,8 +1121,10 @@ add_library(grpc
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
src/core/ext/transport/chttp2/client/insecure/channel_create.c src/core/ext/transport/chttp2/client/insecure/channel_create.c
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
third_party/nanopb/pb_common.c third_party/nanopb/pb_common.c
@ -1990,8 +1993,10 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
src/core/ext/filters/load_reporting/load_reporting.c src/core/ext/filters/load_reporting/load_reporting.c
src/core/ext/filters/load_reporting/load_reporting_filter.c src/core/ext/filters/load_reporting/load_reporting_filter.c
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
third_party/nanopb/pb_common.c third_party/nanopb/pb_common.c
@ -3276,8 +3281,6 @@ foreach(_hdr
include/grpc/impl/codegen/sync_windows.h include/grpc/impl/codegen/sync_windows.h
include/grpc++/impl/codegen/proto_utils.h include/grpc++/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h include/grpc++/impl/codegen/config_protobuf.h
include/grpc++/impl/codegen/thrift_serializer.h
include/grpc++/impl/codegen/thrift_utils.h
) )
string(REPLACE "include/" "" _path ${_hdr}) string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH) get_filename_component(_path ${_path} PATH)
@ -10748,6 +10751,55 @@ target_link_libraries(grpclb_api_test
endif (gRPC_BUILD_TESTS) endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
add_executable(grpclb_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h
test/cpp/end2end/grpclb_end2end_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
protobuf_generate_grpc_cpp(
src/proto/grpc/lb/v1/load_balancer.proto
)
target_include_directories(grpclb_end2end_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_BUILD_INCLUDE_DIR}
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
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(grpclb_end2end_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
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(grpclb_test add_executable(grpclb_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
@ -11108,6 +11160,7 @@ if (gRPC_BUILD_TESTS)
add_executable(memory_test add_executable(memory_test
test/core/support/memory_test.cc test/core/support/memory_test.cc
third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
) )
@ -11126,6 +11179,8 @@ target_include_directories(memory_test
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR}
) )

@ -1154,6 +1154,7 @@ grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
grpclb_end2end_test: $(BINDIR)/$(CONFIG)/grpclb_end2end_test
grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test
http2_client: $(BINDIR)/$(CONFIG)/http2_client http2_client: $(BINDIR)/$(CONFIG)/http2_client
@ -1578,6 +1579,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/grpc_cli \ $(BINDIR)/$(CONFIG)/grpc_cli \
$(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \
$(BINDIR)/$(CONFIG)/grpclb_end2end_test \
$(BINDIR)/$(CONFIG)/grpclb_test \ $(BINDIR)/$(CONFIG)/grpclb_test \
$(BINDIR)/$(CONFIG)/health_service_end2end_test \ $(BINDIR)/$(CONFIG)/health_service_end2end_test \
$(BINDIR)/$(CONFIG)/http2_client \ $(BINDIR)/$(CONFIG)/http2_client \
@ -1699,6 +1701,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/grpc_cli \ $(BINDIR)/$(CONFIG)/grpc_cli \
$(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \
$(BINDIR)/$(CONFIG)/grpclb_end2end_test \
$(BINDIR)/$(CONFIG)/grpclb_test \ $(BINDIR)/$(CONFIG)/grpclb_test \
$(BINDIR)/$(CONFIG)/health_service_end2end_test \ $(BINDIR)/$(CONFIG)/health_service_end2end_test \
$(BINDIR)/$(CONFIG)/http2_client \ $(BINDIR)/$(CONFIG)/http2_client \
@ -2081,6 +2084,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_api_test" $(E) "[RUN] Testing grpclb_api_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_end2end_test || ( echo test grpclb_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_test" $(E) "[RUN] Testing grpclb_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 )
$(E) "[RUN] Testing health_service_end2end_test" $(E) "[RUN] Testing health_service_end2end_test"
@ -3099,8 +3104,10 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \ src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \ third_party/nanopb/pb_common.c \
@ -3938,8 +3945,10 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/filters/load_reporting/load_reporting.c \ src/core/ext/filters/load_reporting/load_reporting.c \
src/core/ext/filters/load_reporting/load_reporting_filter.c \ src/core/ext/filters/load_reporting/load_reporting_filter.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \ third_party/nanopb/pb_common.c \
@ -5157,8 +5166,6 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/sync_windows.h \ include/grpc/impl/codegen/sync_windows.h \
include/grpc++/impl/codegen/proto_utils.h \ include/grpc++/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \ include/grpc++/impl/codegen/config_protobuf.h \
include/grpc++/impl/codegen/thrift_serializer.h \
include/grpc++/impl/codegen/thrift_utils.h \
LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
@ -8272,8 +8279,8 @@ PUBLIC_HEADERS_C += \
LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBARES_SRC)))) LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBARES_SRC))))
$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DHAVE_CONFIG_H $(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
$(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion -Wno-invalid-source-encoding $(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
$(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP) $(LIBARES_OBJS) $(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP) $(LIBARES_OBJS)
$(E) "[AR] Creating $@" $(E) "[AR] Creating $@"
@ -15094,6 +15101,53 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
GRPCLB_END2END_TEST_SRC = \
$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
test/cpp/end2end/grpclb_end2end_test.cc \
GRPCLB_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_END2END_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/grpclb_end2end_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/grpclb_end2end_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_grpclb_end2end_test: $(GRPCLB_END2END_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GRPCLB_END2END_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
GRPCLB_TEST_SRC = \ GRPCLB_TEST_SRC = \
$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
test/cpp/grpclb/grpclb_test.cc \ test/cpp/grpclb/grpclb_test.cc \

@ -80,7 +80,7 @@ task 'dlls' do
grpc_config = ENV['GRPC_CONFIG'] || 'opt' grpc_config = ENV['GRPC_CONFIG'] || 'opt'
verbose = ENV['V'] || '0' verbose = ENV['V'] || '0'
env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result" ' env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result -DCARES_STATICLIB" '
env += 'LDFLAGS=-static ' env += 'LDFLAGS=-static '
env += 'SYSTEM=MINGW32 ' env += 'SYSTEM=MINGW32 '
env += 'EMBED_ZLIB=true ' env += 'EMBED_ZLIB=true '

@ -39,15 +39,16 @@
{ {
'variables': { 'variables': {
'runtime%': 'node', 'runtime%': 'node',
# UV integration in C core is enabled by default. It can be disabled
# by setting this argument to anything else.
'grpc_uv%': 'true',
# Some Node installations use the system installation of OpenSSL, and on # Some Node installations use the system installation of OpenSSL, and on
# some systems, the system OpenSSL still does not have ALPN support. This # some systems, the system OpenSSL still does not have ALPN support. This
# will let users recompile gRPC to work without ALPN. # will let users recompile gRPC to work without ALPN.
'grpc_alpn%': 'true', 'grpc_alpn%': 'true',
# Indicates that the library should be built with gcov. # Indicates that the library should be built with gcov.
'grpc_gcov%': 'false' 'grpc_gcov%': 'false',
# Indicates that the library should be built with compatibility for musl
# libc, so that it can run on Alpine Linux. This is only necessary if not
# building on Alpine Linux
'grpc_alpine%': 'false'
}, },
'target_defaults': { 'target_defaults': {
'configurations': { 'configurations': {
@ -86,17 +87,11 @@
'include' 'include'
], ],
'defines': [ 'defines': [
'GPR_BACKWARDS_COMPATIBILITY_MODE' 'GPR_BACKWARDS_COMPATIBILITY_MODE',
],
'conditions': [
['grpc_uv=="true"', {
'defines': [
'GRPC_ARES=0', 'GRPC_ARES=0',
# Disabling this while bugs are ironed out. Uncomment this to
# re-enable libuv integration in C core.
'GRPC_UV' 'GRPC_UV'
] ],
}], 'conditions': [
['grpc_gcov=="true"', { ['grpc_gcov=="true"', {
'cflags': [ 'cflags': [
'-O0', '-O0',
@ -115,6 +110,11 @@
'-rdynamic', '-rdynamic',
], ],
}], }],
['grpc_alpine=="true"', {
'defines': [
'GPR_MUSL_LIBC_COMPAT'
]
}],
['OS!="win" and runtime=="electron"', { ['OS!="win" and runtime=="electron"', {
"defines": [ "defines": [
'OPENSSL_NO_THREADS' 'OPENSSL_NO_THREADS'
@ -535,6 +535,10 @@
} }
] ]
}, },
]
}],
['OS == "win"', {
'targets': [
# Only want to compile zlib under Windows # Only want to compile zlib under Windows
{ {
'cflags': [ 'cflags': [
@ -569,7 +573,6 @@
}] }]
], ],
'targets': [ 'targets': [
{ {
'cflags': [ 'cflags': [
'-std=c99', '-std=c99',
@ -648,7 +651,6 @@
'type': 'static_library', 'type': 'static_library',
'dependencies': [ 'dependencies': [
'gpr', 'gpr',
'node_modules/cares/deps/cares/cares.gyp:cares',
], ],
'sources': [ 'sources': [
'src/core/lib/surface/init.c', 'src/core/lib/surface/init.c',
@ -855,8 +857,10 @@
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c', 'third_party/nanopb/pb_common.c',
@ -940,20 +944,16 @@
"src/node/ext/call_credentials.cc", "src/node/ext/call_credentials.cc",
"src/node/ext/channel.cc", "src/node/ext/channel.cc",
"src/node/ext/channel_credentials.cc", "src/node/ext/channel_credentials.cc",
"src/node/ext/completion_queue_threadpool.cc", "src/node/ext/completion_queue.cc",
"src/node/ext/completion_queue_uv.cc",
"src/node/ext/node_grpc.cc", "src/node/ext/node_grpc.cc",
"src/node/ext/server.cc", "src/node/ext/server.cc",
"src/node/ext/server_credentials.cc", "src/node/ext/server_credentials.cc",
"src/node/ext/server_generic.cc",
"src/node/ext/server_uv.cc",
"src/node/ext/slice.cc", "src/node/ext/slice.cc",
"src/node/ext/timeval.cc", "src/node/ext/timeval.cc",
], ],
"dependencies": [ "dependencies": [
"grpc", "grpc",
"gpr", "gpr",
"node_modules/cares/deps/cares/cares.gyp:cares",
] ]
}, },
{ {

@ -488,13 +488,17 @@ filegroups:
- grpc_base - grpc_base
- name: grpc_lb_policy_grpclb - name: grpc_lb_policy_grpclb
headers: headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src: src:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
plugin: grpc_lb_policy_grpclb plugin: grpc_lb_policy_grpclb
@ -504,13 +508,17 @@ filegroups:
- nanopb - nanopb
- name: grpc_lb_policy_grpclb_secure - name: grpc_lb_policy_grpclb_secure
headers: headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src: src:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
plugin: grpc_lb_policy_grpclb plugin: grpc_lb_policy_grpclb
@ -979,13 +987,6 @@ filegroups:
- include/grpc++/test/server_context_test_spouse.h - include/grpc++/test/server_context_test_spouse.h
deps: deps:
- grpc++ - grpc++
- name: thrift_util
language: c++
public_headers:
- include/grpc++/impl/codegen/thrift_serializer.h
- include/grpc++/impl/codegen/thrift_utils.h
uses:
- grpc++_codegen_base
libs: libs:
- name: gpr - name: gpr
build: all build: all
@ -1283,7 +1284,6 @@ libs:
- grpc++_codegen_base_src - grpc++_codegen_base_src
- grpc++_codegen_proto - grpc++_codegen_proto
- grpc++_config_proto - grpc++_config_proto
- thrift_util
- name: grpc++_unsecure - name: grpc++_unsecure
build: all build: all
language: c++ language: c++
@ -3812,6 +3812,20 @@ targets:
- grpc_test_util - grpc_test_util
- grpc++ - grpc++
- grpc - grpc
- name: grpclb_end2end_test
gtest: true
build: test
language: c++
src:
- src/proto/grpc/lb/v1/load_balancer.proto
- test/cpp/end2end/grpclb_end2end_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- name: grpclb_test - name: grpclb_test
gtest: false gtest: false
build: test build: test
@ -4498,10 +4512,11 @@ configs:
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=tools/ubsan_suppressions.txt UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=tools/ubsan_suppressions.txt
defaults: defaults:
ares: ares:
CFLAGS: -Wno-sign-conversion -Wno-invalid-source-encoding CFLAGS: -Wno-sign-conversion $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux)
$(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden
-D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DHAVE_CONFIG_H -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst
MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
benchmark: benchmark:
CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
boringssl: boringssl:
@ -4547,13 +4562,10 @@ node_modules:
- src/node/ext/call_credentials.cc - src/node/ext/call_credentials.cc
- src/node/ext/channel.cc - src/node/ext/channel.cc
- src/node/ext/channel_credentials.cc - src/node/ext/channel_credentials.cc
- src/node/ext/completion_queue_threadpool.cc - src/node/ext/completion_queue.cc
- src/node/ext/completion_queue_uv.cc
- src/node/ext/node_grpc.cc - src/node/ext/node_grpc.cc
- src/node/ext/server.cc - src/node/ext/server.cc
- src/node/ext/server_credentials.cc - src/node/ext/server_credentials.cc
- src/node/ext/server_generic.cc
- src/node/ext/server_uv.cc
- src/node/ext/slice.cc - src/node/ext/slice.cc
- src/node/ext/timeval.cc - src/node/ext/timeval.cc
openssl_fallback: openssl_fallback:

@ -291,8 +291,10 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \ src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \ third_party/nanopb/pb_common.c \

@ -434,8 +434,10 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h', 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'third_party/nanopb/pb.h', 'third_party/nanopb/pb.h',
@ -668,8 +670,10 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c', 'third_party/nanopb/pb_common.c',
@ -895,8 +899,10 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h', 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'third_party/nanopb/pb.h', 'third_party/nanopb/pb.h',

@ -350,8 +350,10 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/uri_parser.h ) s.files += %w( src/core/ext/filters/client_channel/uri_parser.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h ) s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
s.files += %w( third_party/nanopb/pb.h ) s.files += %w( third_party/nanopb/pb.h )
@ -584,8 +586,10 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c ) s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c ) s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c ) s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
s.files += %w( third_party/nanopb/pb_common.c ) s.files += %w( third_party/nanopb/pb_common.c )

@ -364,28 +364,6 @@ class CallOpRecvMessage {
bool allow_not_getting_message_; bool allow_not_getting_message_;
}; };
namespace CallOpGenericRecvMessageHelper {
class DeserializeFunc {
public:
virtual Status Deserialize(grpc_byte_buffer* buf) = 0;
virtual ~DeserializeFunc() {}
};
template <class R>
class DeserializeFuncType final : public DeserializeFunc {
public:
DeserializeFuncType(R* message) : message_(message) {}
Status Deserialize(grpc_byte_buffer* buf) override {
return SerializationTraits<R>::Deserialize(buf, message_);
}
~DeserializeFuncType() override {}
private:
R* message_; // Not a managed pointer because management is external to this
};
} // namespace CallOpGenericRecvMessageHelper
class CallOpGenericRecvMessage { class CallOpGenericRecvMessage {
public: public:
CallOpGenericRecvMessage() CallOpGenericRecvMessage()
@ -393,11 +371,9 @@ class CallOpGenericRecvMessage {
template <class R> template <class R>
void RecvMessage(R* message) { void RecvMessage(R* message) {
// Use an explicit base class pointer to avoid resolution error in the deserialize_ = [message](grpc_byte_buffer* buf) -> Status {
// following unique_ptr::reset for some old implementations. return SerializationTraits<R>::Deserialize(buf, message);
CallOpGenericRecvMessageHelper::DeserializeFunc* func = };
new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message);
deserialize_.reset(func);
} }
// Do not change status if no message is received. // Do not change status if no message is received.
@ -420,7 +396,7 @@ class CallOpGenericRecvMessage {
if (recv_buf_) { if (recv_buf_) {
if (*status) { if (*status) {
got_message = true; got_message = true;
*status = deserialize_->Deserialize(recv_buf_).ok(); *status = deserialize_(recv_buf_).ok();
} else { } else {
got_message = false; got_message = false;
g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_); g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_);
@ -431,11 +407,12 @@ class CallOpGenericRecvMessage {
*status = false; *status = false;
} }
} }
deserialize_.reset(); deserialize_ = DeserializeFunc();
} }
private: private:
std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_; typedef std::function<Status(grpc_byte_buffer*)> DeserializeFunc;
DeserializeFunc deserialize_;
grpc_byte_buffer* recv_buf_; grpc_byte_buffer* recv_buf_;
bool allow_not_getting_message_; bool allow_not_getting_message_;
}; };

@ -293,6 +293,9 @@ each time recvmsg (or equivalent) is called */
"grpc.experimental.tcp_min_read_chunk_size" "grpc.experimental.tcp_min_read_chunk_size"
#define GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE \ #define GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE \
"grpc.experimental.tcp_max_read_chunk_size" "grpc.experimental.tcp_max_read_chunk_size"
/* Timeout in milliseconds to use for calls to the grpclb load balancer.
If 0 or unset, the balancer calls will have no deadline. */
#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_timeout_ms"
/** \} */ /** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a /** Result of a grpc call. If the caller satisfies the prerequisites of a

@ -189,7 +189,7 @@
#ifdef __GLIBC__ #ifdef __GLIBC__
#define GPR_POSIX_CRASH_HANDLER 1 #define GPR_POSIX_CRASH_HANDLER 1
#else /* musl libc */ #else /* musl libc */
#define GRPC_MSG_IOVLEN_TYPE int #define GPR_MUSL_LIBC_COMPAT 1
#endif #endif
#elif defined(__APPLE__) #elif defined(__APPLE__)
#include <Availability.h> #include <Availability.h>

@ -34,8 +34,7 @@
"lodash": "^4.15.0", "lodash": "^4.15.0",
"nan": "^2.0.0", "nan": "^2.0.0",
"node-pre-gyp": "^0.6.0", "node-pre-gyp": "^0.6.0",
"protobufjs": "^6.7.0", "protobufjs": "^6.7.0"
"cares": "^1.1.5"
}, },
"devDependencies": { "devDependencies": {
"async": "^2.0.1", "async": "^2.0.1",

@ -359,8 +359,10 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" /> <file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
@ -593,8 +595,10 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" /> <file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />

@ -144,6 +144,8 @@ CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',)
CYTHON_HELPER_C_FILES = () CYTHON_HELPER_C_FILES = ()
CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES) CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES)
if "win32" in sys.platform and "64bit" in platform.architecture()[0]:
CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES)
EXTENSION_INCLUDE_DIRECTORIES = ( EXTENSION_INCLUDE_DIRECTORIES = (
(PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE + ZLIB_INCLUDE + (PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE + ZLIB_INCLUDE +
@ -163,7 +165,9 @@ DEFINE_MACROS = (
if "win32" in sys.platform: if "win32" in sys.platform:
DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1), ('CARES_STATICLIB', 1),) DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1), ('CARES_STATICLIB', 1),)
if '64bit' in platform.architecture()[0]: if '64bit' in platform.architecture()[0]:
DEFINE_MACROS += (('MS_WIN64', 1),) # TODO(zyc): Re-enble c-ares on x64 windows after fixing the
# ares_library_init compilation issue
DEFINE_MACROS += (('MS_WIN64', 1), ('GRPC_ARES', 0),)
elif sys.version_info >= (3, 5): elif sys.version_info >= (3, 5):
# For some reason, this is needed to get access to inet_pton/inet_ntop # For some reason, this is needed to get access to inet_pton/inet_ntop
# on msvc, but only for 32 bits # on msvc, but only for 32 bits

@ -804,6 +804,12 @@ void PrintHeaderService(grpc_generator::Printer *printer,
" public:\n"); " public:\n");
printer->Indent(); printer->Indent();
// Service metadata
printer->Print(*vars,
"static constexpr char const* service_full_name() {\n"
" return \"$Package$$Service$\";\n"
"}\n");
// Client side // Client side
printer->Print( printer->Print(
"class StubInterface {\n" "class StubInterface {\n"

@ -622,9 +622,17 @@ bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
for (StringPairSet::iterator it = imports_set.begin(); for (StringPairSet::iterator it = imports_set.begin();
it != imports_set.end(); ++it) { it != imports_set.end(); ++it) {
var["ModuleName"] = std::get<0>(*it); auto module_name = std::get<0>(*it);
var["ModuleAlias"] = std::get<1>(*it); var["ModuleAlias"] = std::get<1>(*it);
out->Print(var, "import $ModuleName$ as $ModuleAlias$\n"); const size_t last_dot_pos = module_name.rfind('.');
if (last_dot_pos == grpc::string::npos) {
var["ImportStatement"] = "import " + module_name;
} else {
var["ImportStatement"] = "from " + module_name.substr(0, last_dot_pos) +
" import " +
module_name.substr(last_dot_pos + 1);
}
out->Print(var, "$ImportStatement$ as $ModuleAlias$\n");
} }
} }
return true; return true;

@ -760,12 +760,6 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
#define CANCELLED_CALL ((grpc_subchannel_call *)1) #define CANCELLED_CALL ((grpc_subchannel_call *)1)
typedef enum {
/* zero so that it can be default-initialized */
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING = 0,
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
} subchannel_creation_phase;
/** Call data. Holds a pointer to grpc_subchannel_call and the /** Call data. Holds a pointer to grpc_subchannel_call and the
associated machinery to create such a pointer. associated machinery to create such a pointer.
Handles queueing of stream ops until a call object is ready, waiting Handles queueing of stream ops until a call object is ready, waiting
@ -793,8 +787,9 @@ typedef struct client_channel_call_data {
gpr_atm subchannel_call; gpr_atm subchannel_call;
gpr_arena *arena; gpr_arena *arena;
subchannel_creation_phase creation_phase; bool pick_pending;
grpc_connected_subchannel *connected_subchannel; grpc_connected_subchannel *connected_subchannel;
grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
grpc_polling_entity *pollent; grpc_polling_entity *pollent;
grpc_transport_stream_op_batch **waiting_ops; grpc_transport_stream_op_batch **waiting_ops;
@ -914,11 +909,10 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_call_element *elem = arg; grpc_call_element *elem = arg;
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
GPR_ASSERT(calld->creation_phase == GPR_ASSERT(calld->pick_pending);
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); calld->pick_pending = false;
grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent, grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent,
chand->interested_parties); chand->interested_parties);
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
if (calld->connected_subchannel == NULL) { if (calld->connected_subchannel == NULL) {
gpr_atm_no_barrier_store(&calld->subchannel_call, 1); gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
fail_locked(exec_ctx, calld, fail_locked(exec_ctx, calld,
@ -944,7 +938,8 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
.path = calld->path, .path = calld->path,
.start_time = calld->call_start_time, .start_time = calld->call_start_time,
.deadline = calld->deadline, .deadline = calld->deadline,
.arena = calld->arena}; .arena = calld->arena,
.context = calld->subchannel_call_context};
grpc_error *new_error = grpc_connected_subchannel_create_call( grpc_error *new_error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call); exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
gpr_atm_rel_store(&calld->subchannel_call, gpr_atm_rel_store(&calld->subchannel_call,
@ -973,6 +968,7 @@ typedef struct {
grpc_metadata_batch *initial_metadata; grpc_metadata_batch *initial_metadata;
uint32_t initial_metadata_flags; uint32_t initial_metadata_flags;
grpc_connected_subchannel **connected_subchannel; grpc_connected_subchannel **connected_subchannel;
grpc_call_context_element *subchannel_call_context;
grpc_closure *on_ready; grpc_closure *on_ready;
grpc_call_element *elem; grpc_call_element *elem;
grpc_closure closure; grpc_closure closure;
@ -984,8 +980,8 @@ typedef struct {
static bool pick_subchannel_locked( static bool pick_subchannel_locked(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready, grpc_connected_subchannel **connected_subchannel,
grpc_error *error); grpc_call_context_element *subchannel_call_context, grpc_closure *on_ready);
static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg, static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) { grpc_error *error) {
@ -997,49 +993,49 @@ static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
} else { } else {
if (pick_subchannel_locked(exec_ctx, cpa->elem, cpa->initial_metadata, if (pick_subchannel_locked(exec_ctx, cpa->elem, cpa->initial_metadata,
cpa->initial_metadata_flags, cpa->initial_metadata_flags,
cpa->connected_subchannel, cpa->on_ready, cpa->connected_subchannel,
GRPC_ERROR_NONE)) { cpa->subchannel_call_context, cpa->on_ready)) {
grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE); grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE);
} }
} }
gpr_free(cpa); gpr_free(cpa);
} }
static bool pick_subchannel_locked( static void cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready,
grpc_error *error) { grpc_error *error) {
GPR_TIMER_BEGIN("pick_subchannel", 0);
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
continue_picking_args *cpa;
grpc_closure *closure;
GPR_ASSERT(connected_subchannel);
if (initial_metadata == NULL) {
if (chand->lb_policy != NULL) { if (chand->lb_policy != NULL) {
grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy, grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy,
connected_subchannel, &calld->connected_subchannel,
GRPC_ERROR_REF(error)); GRPC_ERROR_REF(error));
} }
for (closure = chand->waiting_for_config_closures.head; closure != NULL; for (grpc_closure *closure = chand->waiting_for_config_closures.head;
closure = closure->next_data.next) { closure != NULL; closure = closure->next_data.next) {
cpa = closure->cb_arg; continue_picking_args *cpa = closure->cb_arg;
if (cpa->connected_subchannel == connected_subchannel) { if (cpa->connected_subchannel == &calld->connected_subchannel) {
cpa->connected_subchannel = NULL; cpa->connected_subchannel = NULL;
grpc_closure_sched(exec_ctx, cpa->on_ready, grpc_closure_sched(exec_ctx, cpa->on_ready,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick cancelled", &error, 1)); "Pick cancelled", &error, 1));
} }
} }
GPR_TIMER_END("pick_subchannel", 0);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
return true; }
}
GPR_ASSERT(error == GRPC_ERROR_NONE); static bool pick_subchannel_locked(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel,
grpc_call_context_element *subchannel_call_context,
grpc_closure *on_ready) {
GPR_TIMER_BEGIN("pick_subchannel", 0);
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
GPR_ASSERT(connected_subchannel);
if (chand->lb_policy != NULL) { if (chand->lb_policy != NULL) {
apply_final_configuration_locked(exec_ctx, elem); apply_final_configuration_locked(exec_ctx, elem);
grpc_lb_policy *lb_policy = chand->lb_policy; grpc_lb_policy *lb_policy = chand->lb_policy;
@ -1062,8 +1058,7 @@ static bool pick_subchannel_locked(
} }
} }
const grpc_lb_policy_pick_args inputs = { const grpc_lb_policy_pick_args inputs = {
initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem, initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem};
gpr_inf_future(GPR_CLOCK_MONOTONIC)};
// Wrap the user-provided callback in order to hold a strong reference to // Wrap the user-provided callback in order to hold a strong reference to
// the LB policy for the duration of the pick. // the LB policy for the duration of the pick.
@ -1076,8 +1071,8 @@ static bool pick_subchannel_locked(
GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel_wrapping"); GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel_wrapping");
w_on_pick_arg->lb_policy = lb_policy; w_on_pick_arg->lb_policy = lb_policy;
const bool pick_done = grpc_lb_policy_pick_locked( const bool pick_done = grpc_lb_policy_pick_locked(
exec_ctx, lb_policy, &inputs, connected_subchannel, NULL, exec_ctx, lb_policy, &inputs, connected_subchannel,
&w_on_pick_arg->wrapper_closure); subchannel_call_context, NULL, &w_on_pick_arg->wrapper_closure);
if (pick_done) { if (pick_done) {
/* synchronous grpc_lb_policy_pick call. Unref the LB policy. */ /* synchronous grpc_lb_policy_pick call. Unref the LB policy. */
GRPC_LB_POLICY_UNREF(exec_ctx, w_on_pick_arg->lb_policy, GRPC_LB_POLICY_UNREF(exec_ctx, w_on_pick_arg->lb_policy,
@ -1096,10 +1091,11 @@ static bool pick_subchannel_locked(
&chand->on_resolver_result_changed); &chand->on_resolver_result_changed);
} }
if (chand->resolver != NULL) { if (chand->resolver != NULL) {
cpa = gpr_malloc(sizeof(*cpa)); continue_picking_args *cpa = gpr_malloc(sizeof(*cpa));
cpa->initial_metadata = initial_metadata; cpa->initial_metadata = initial_metadata;
cpa->initial_metadata_flags = initial_metadata_flags; cpa->initial_metadata_flags = initial_metadata_flags;
cpa->connected_subchannel = connected_subchannel; cpa->connected_subchannel = connected_subchannel;
cpa->subchannel_call_context = subchannel_call_context;
cpa->on_ready = on_ready; cpa->on_ready = on_ready;
cpa->elem = elem; cpa->elem = elem;
grpc_closure_init(&cpa->closure, continue_picking_locked, cpa, grpc_closure_init(&cpa->closure, continue_picking_locked, cpa,
@ -1151,16 +1147,13 @@ static void start_transport_stream_op_batch_locked_inner(
error to the caller when the first op does get passed down. */ error to the caller when the first op does get passed down. */
calld->cancel_error = calld->cancel_error =
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error); GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error);
switch (calld->creation_phase) { if (calld->pick_pending) {
case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING: cancel_pick_locked(
fail_locked(exec_ctx, calld, exec_ctx, elem,
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error)); GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
break; } else {
case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL: fail_locked(exec_ctx, calld,
pick_subchannel_locked(
exec_ctx, elem, NULL, 0, &calld->connected_subchannel, NULL,
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error)); GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
break;
} }
grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch_finish_with_failure(
exec_ctx, op, exec_ctx, op,
@ -1170,9 +1163,9 @@ static void start_transport_stream_op_batch_locked_inner(
} }
} }
/* if we don't have a subchannel, try to get one */ /* if we don't have a subchannel, try to get one */
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && if (!calld->pick_pending && calld->connected_subchannel == NULL &&
calld->connected_subchannel == NULL && op->send_initial_metadata) { op->send_initial_metadata) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; calld->pick_pending = true;
grpc_closure_init(&calld->next_step, subchannel_ready_locked, elem, grpc_closure_init(&calld->next_step, subchannel_ready_locked, elem,
grpc_combiner_scheduler(chand->combiner, true)); grpc_combiner_scheduler(chand->combiner, true));
GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel"); GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
@ -1183,8 +1176,9 @@ static void start_transport_stream_op_batch_locked_inner(
exec_ctx, elem, exec_ctx, elem,
op->payload->send_initial_metadata.send_initial_metadata, op->payload->send_initial_metadata.send_initial_metadata,
op->payload->send_initial_metadata.send_initial_metadata_flags, op->payload->send_initial_metadata.send_initial_metadata_flags,
&calld->connected_subchannel, &calld->next_step, GRPC_ERROR_NONE)) { &calld->connected_subchannel, calld->subchannel_call_context,
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; &calld->next_step)) {
calld->pick_pending = false;
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel"); GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
} else { } else {
grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent, grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent,
@ -1192,15 +1186,15 @@ static void start_transport_stream_op_batch_locked_inner(
} }
} }
/* if we've got a subchannel, then let's ask it to create a call */ /* if we've got a subchannel, then let's ask it to create a call */
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && if (!calld->pick_pending && calld->connected_subchannel != NULL) {
calld->connected_subchannel != NULL) {
grpc_subchannel_call *subchannel_call = NULL; grpc_subchannel_call *subchannel_call = NULL;
const grpc_connected_subchannel_call_args call_args = { const grpc_connected_subchannel_call_args call_args = {
.pollent = calld->pollent, .pollent = calld->pollent,
.path = calld->path, .path = calld->path,
.start_time = calld->call_start_time, .start_time = calld->call_start_time,
.deadline = calld->deadline, .deadline = calld->deadline,
.arena = calld->arena}; .arena = calld->arena,
.context = calld->subchannel_call_context};
grpc_error *error = grpc_connected_subchannel_create_call( grpc_error *error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call); exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
gpr_atm_rel_store(&calld->subchannel_call, gpr_atm_rel_store(&calld->subchannel_call,
@ -1349,12 +1343,18 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
then_schedule_closure = NULL; then_schedule_closure = NULL;
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call"); GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
} }
GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING); GPR_ASSERT(!calld->pick_pending);
GPR_ASSERT(calld->waiting_ops_count == 0); GPR_ASSERT(calld->waiting_ops_count == 0);
if (calld->connected_subchannel != NULL) { if (calld->connected_subchannel != NULL) {
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel, GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel,
"picked"); "picked");
} }
for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
if (calld->subchannel_call_context[i].value != NULL) {
calld->subchannel_call_context[i].destroy(
calld->subchannel_call_context[i].value);
}
}
gpr_free(calld->waiting_ops); gpr_free(calld->waiting_ops);
grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE); grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
} }
@ -1450,12 +1450,12 @@ static void watch_connectivity_state_locked(grpc_exec_ctx *exec_ctx, void *arg,
void grpc_client_channel_watch_connectivity_state( void grpc_client_channel_watch_connectivity_state(
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
grpc_connectivity_state *state, grpc_closure *on_complete) { grpc_connectivity_state *state, grpc_closure *closure) {
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
external_connectivity_watcher *w = gpr_malloc(sizeof(*w)); external_connectivity_watcher *w = gpr_malloc(sizeof(*w));
w->chand = chand; w->chand = chand;
w->pollset = pollset; w->pollset = pollset;
w->on_complete = on_complete; w->on_complete = closure;
w->state = state; w->state = state;
grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset); grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
GRPC_CHANNEL_STACK_REF(w->chand->owning_stack, GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,

@ -119,9 +119,10 @@ void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx,
int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, grpc_connected_subchannel **target,
grpc_call_context_element *context,
void **user_data, grpc_closure *on_complete) { void **user_data, grpc_closure *on_complete) {
return policy->vtable->pick_locked(exec_ctx, policy, pick_args, target, return policy->vtable->pick_locked(exec_ctx, policy, pick_args, target,
user_data, on_complete); context, user_data, on_complete);
} }
void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx *exec_ctx, void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx *exec_ctx,

@ -43,9 +43,6 @@
typedef struct grpc_lb_policy grpc_lb_policy; typedef struct grpc_lb_policy grpc_lb_policy;
typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable; typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable;
typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel,
grpc_status_code status, const char *errmsg);
struct grpc_lb_policy { struct grpc_lb_policy {
const grpc_lb_policy_vtable *vtable; const grpc_lb_policy_vtable *vtable;
gpr_atm ref_pair; gpr_atm ref_pair;
@ -65,8 +62,6 @@ typedef struct grpc_lb_policy_pick_args {
uint32_t initial_metadata_flags; uint32_t initial_metadata_flags;
/** Storage for LB token in \a initial_metadata, or NULL if not used */ /** Storage for LB token in \a initial_metadata, or NULL if not used */
grpc_linked_mdelem *lb_token_mdelem_storage; grpc_linked_mdelem *lb_token_mdelem_storage;
/** Deadline for the call to the LB server */
gpr_timespec deadline;
} grpc_lb_policy_pick_args; } grpc_lb_policy_pick_args;
struct grpc_lb_policy_vtable { struct grpc_lb_policy_vtable {
@ -76,7 +71,8 @@ struct grpc_lb_policy_vtable {
/** \see grpc_lb_policy_pick */ /** \see grpc_lb_policy_pick */
int (*pick_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, int (*pick_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, void **user_data, grpc_connected_subchannel **target,
grpc_call_context_element *context, void **user_data,
grpc_closure *on_complete); grpc_closure *on_complete);
/** \see grpc_lb_policy_cancel_pick */ /** \see grpc_lb_policy_cancel_pick */
@ -156,6 +152,8 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
\a target will be set to the selected subchannel, or NULL on failure. \a target will be set to the selected subchannel, or NULL on failure.
Upon success, \a user_data will be set to whatever opaque information Upon success, \a user_data will be set to whatever opaque information
may need to be propagated from the LB policy, or NULL if not needed. may need to be propagated from the LB policy, or NULL if not needed.
\a context will be populated with context to pass to the subchannel
call, if needed.
If the pick succeeds and a result is known immediately, a non-zero If the pick succeeds and a result is known immediately, a non-zero
value will be returned. Otherwise, \a on_complete will be invoked value will be returned. Otherwise, \a on_complete will be invoked
@ -167,6 +165,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, grpc_connected_subchannel **target,
grpc_call_context_element *context,
void **user_data, grpc_closure *on_complete); void **user_data, grpc_closure *on_complete);
/** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping) /** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping)

@ -0,0 +1,153 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/profiling/timers.h"
static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
return GRPC_ERROR_NONE;
}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {}
typedef struct {
// Stats object to update.
grpc_grpclb_client_stats *client_stats;
// State for intercepting send_initial_metadata.
grpc_closure on_complete_for_send;
grpc_closure *original_on_complete_for_send;
bool send_initial_metadata_succeeded;
// State for intercepting recv_initial_metadata.
grpc_closure recv_initial_metadata_ready;
grpc_closure *original_recv_initial_metadata_ready;
bool recv_initial_metadata_succeeded;
} call_data;
static void on_complete_for_send(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
call_data *calld = arg;
if (error == GRPC_ERROR_NONE) {
calld->send_initial_metadata_succeeded = true;
}
grpc_closure_run(exec_ctx, calld->original_on_complete_for_send,
GRPC_ERROR_REF(error));
}
static void recv_initial_metadata_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
call_data *calld = arg;
if (error == GRPC_ERROR_NONE) {
calld->recv_initial_metadata_succeeded = true;
}
grpc_closure_run(exec_ctx, calld->original_recv_initial_metadata_ready,
GRPC_ERROR_REF(error));
}
static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
const grpc_call_element_args *args) {
call_data *calld = elem->call_data;
// Get stats object from context and take a ref.
GPR_ASSERT(args->context != NULL);
GPR_ASSERT(args->context[GRPC_GRPCLB_CLIENT_STATS].value != NULL);
calld->client_stats = grpc_grpclb_client_stats_ref(
args->context[GRPC_GRPCLB_CLIENT_STATS].value);
// Record call started.
grpc_grpclb_client_stats_add_call_started(calld->client_stats);
return GRPC_ERROR_NONE;
}
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
grpc_closure *ignored) {
call_data *calld = elem->call_data;
// Record call finished, optionally setting client_failed_to_send and
// received.
grpc_grpclb_client_stats_add_call_finished(
false /* drop_for_rate_limiting */, false /* drop_for_load_balancing */,
!calld->send_initial_metadata_succeeded /* client_failed_to_send */,
calld->recv_initial_metadata_succeeded /* known_received */,
calld->client_stats);
// All done, so unref the stats object.
grpc_grpclb_client_stats_unref(calld->client_stats);
}
static void start_transport_stream_op_batch(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op_batch *batch) {
call_data *calld = elem->call_data;
GPR_TIMER_BEGIN("clr_start_transport_stream_op_batch", 0);
// Intercept send_initial_metadata.
if (batch->send_initial_metadata) {
calld->original_on_complete_for_send = batch->on_complete;
grpc_closure_init(&calld->on_complete_for_send, on_complete_for_send, calld,
grpc_schedule_on_exec_ctx);
batch->on_complete = &calld->on_complete_for_send;
}
// Intercept recv_initial_metadata.
if (batch->recv_initial_metadata) {
calld->original_recv_initial_metadata_ready =
batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
grpc_closure_init(&calld->recv_initial_metadata_ready,
recv_initial_metadata_ready, calld,
grpc_schedule_on_exec_ctx);
batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
&calld->recv_initial_metadata_ready;
}
// Chain to next filter.
grpc_call_next_op(exec_ctx, elem, batch);
GPR_TIMER_END("clr_start_transport_stream_op_batch", 0);
}
const grpc_channel_filter grpc_client_load_reporting_filter = {
start_transport_stream_op_batch,
grpc_channel_next_op,
sizeof(call_data),
init_call_elem,
grpc_call_stack_ignore_set_pollset_or_pollset_set,
destroy_call_elem,
0, // sizeof(channel_data)
init_channel_elem,
destroy_channel_elem,
grpc_call_next_get_peer,
grpc_channel_next_get_info,
"client_load_reporting"};

@ -31,45 +31,12 @@
* *
*/ */
#ifndef GRPC_UV #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H
#include "server.h" #include "src/core/lib/channel/channel_stack.h"
#include <nan.h> extern const grpc_channel_filter grpc_client_load_reporting_filter;
#include <node.h>
#include "grpc/grpc.h"
#include "grpc/support/time.h"
namespace grpc { #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H \
namespace node { */
Server::Server(grpc_server *server) : wrapped_server(server) {
grpc_completion_queue_attributes attrs = {
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_NON_LISTENING};
shutdown_queue = grpc_completion_queue_create(
grpc_completion_queue_factory_lookup(&attrs), &attrs, NULL);
grpc_server_register_completion_queue(server, shutdown_queue, NULL);
}
Server::~Server() {
this->ShutdownServer();
grpc_completion_queue_shutdown(this->shutdown_queue);
grpc_completion_queue_destroy(this->shutdown_queue);
}
void Server::ShutdownServer() {
if (this->wrapped_server != NULL) {
grpc_server_shutdown_and_notify(this->wrapped_server, this->shutdown_queue,
NULL);
grpc_server_cancel_all_calls(this->wrapped_server);
grpc_completion_queue_pluck(this->shutdown_queue, NULL,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
grpc_server_destroy(this->wrapped_server);
this->wrapped_server = NULL;
}
}
} // namespace grpc
} // namespace node
#endif /* GRPC_UV */

@ -95,8 +95,7 @@
headers. Therefore, sockaddr.h must always be included first */ headers. Therefore, sockaddr.h must always be included first */
#include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr.h"
#include <errno.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <grpc/byte_buffer_reader.h> #include <grpc/byte_buffer_reader.h>
@ -108,13 +107,16 @@
#include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/sockaddr_utils.h"
@ -126,6 +128,7 @@
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/static_metadata.h"
#define GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS 20 #define GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS 20
@ -147,6 +150,10 @@ static grpc_error *initial_metadata_add_lb_token(
lb_token_mdelem_storage, lb_token); lb_token_mdelem_storage, lb_token);
} }
static void destroy_client_stats(void *arg) {
grpc_grpclb_client_stats_unref(arg);
}
typedef struct wrapped_rr_closure_arg { typedef struct wrapped_rr_closure_arg {
/* the closure instance using this struct as argument */ /* the closure instance using this struct as argument */
grpc_closure wrapper_closure; grpc_closure wrapper_closure;
@ -163,6 +170,13 @@ typedef struct wrapped_rr_closure_arg {
* initial metadata */ * initial metadata */
grpc_connected_subchannel **target; grpc_connected_subchannel **target;
/* the context to be populated for the subchannel call */
grpc_call_context_element *context;
/* Stats for client-side load reporting. Note that this holds a
* reference, which must be either passed on via context or unreffed. */
grpc_grpclb_client_stats *client_stats;
/* the LB token associated with the pick */ /* the LB token associated with the pick */
grpc_mdelem lb_token; grpc_mdelem lb_token;
@ -202,6 +216,12 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
(void *)*wc_arg->target, (void *)wc_arg->rr_policy); (void *)*wc_arg->target, (void *)wc_arg->rr_policy);
abort(); abort();
} }
// Pass on client stats via context. Passes ownership of the reference.
GPR_ASSERT(wc_arg->client_stats != NULL);
wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].value = wc_arg->client_stats;
wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].destroy = destroy_client_stats;
} else {
grpc_grpclb_client_stats_unref(wc_arg->client_stats);
} }
if (grpc_lb_glb_trace) { if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, "Unreffing RR %p", (void *)wc_arg->rr_policy); gpr_log(GPR_INFO, "Unreffing RR %p", (void *)wc_arg->rr_policy);
@ -237,6 +257,7 @@ typedef struct pending_pick {
static void add_pending_pick(pending_pick **root, static void add_pending_pick(pending_pick **root,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, grpc_connected_subchannel **target,
grpc_call_context_element *context,
grpc_closure *on_complete) { grpc_closure *on_complete) {
pending_pick *pp = gpr_zalloc(sizeof(*pp)); pending_pick *pp = gpr_zalloc(sizeof(*pp));
pp->next = *root; pp->next = *root;
@ -244,6 +265,7 @@ static void add_pending_pick(pending_pick **root,
pp->target = target; pp->target = target;
pp->wrapped_on_complete_arg.wrapped_closure = on_complete; pp->wrapped_on_complete_arg.wrapped_closure = on_complete;
pp->wrapped_on_complete_arg.target = target; pp->wrapped_on_complete_arg.target = target;
pp->wrapped_on_complete_arg.context = context;
pp->wrapped_on_complete_arg.initial_metadata = pick_args->initial_metadata; pp->wrapped_on_complete_arg.initial_metadata = pick_args->initial_metadata;
pp->wrapped_on_complete_arg.lb_token_mdelem_storage = pp->wrapped_on_complete_arg.lb_token_mdelem_storage =
pick_args->lb_token_mdelem_storage; pick_args->lb_token_mdelem_storage;
@ -287,8 +309,8 @@ typedef struct glb_lb_policy {
grpc_client_channel_factory *cc_factory; grpc_client_channel_factory *cc_factory;
grpc_channel_args *args; grpc_channel_args *args;
/** deadline for the LB's call */ /** timeout in milliseconds for the LB call. 0 means no deadline. */
gpr_timespec deadline; int lb_call_timeout_ms;
/** for communicating with the LB server */ /** for communicating with the LB server */
grpc_channel *lb_channel; grpc_channel *lb_channel;
@ -316,6 +338,10 @@ typedef struct glb_lb_policy {
/************************************************************/ /************************************************************/
/* client data associated with the LB server communication */ /* client data associated with the LB server communication */
/************************************************************/ /************************************************************/
/* Finished sending initial request. */
grpc_closure lb_on_sent_initial_request;
/* Status from the LB server has been received. This signals the end of the LB /* Status from the LB server has been received. This signals the end of the LB
* call. */ * call. */
grpc_closure lb_on_server_status_received; grpc_closure lb_on_server_status_received;
@ -348,6 +374,23 @@ typedef struct glb_lb_policy {
/** LB call retry timer */ /** LB call retry timer */
grpc_timer lb_call_retry_timer; grpc_timer lb_call_retry_timer;
bool initial_request_sent;
bool seen_initial_response;
/* Stats for client-side load reporting. Should be unreffed and
* recreated whenever lb_call is replaced. */
grpc_grpclb_client_stats *client_stats;
/* Interval and timer for next client load report. */
gpr_timespec client_stats_report_interval;
grpc_timer client_load_report_timer;
bool client_load_report_timer_pending;
bool last_client_load_report_counters_were_zero;
/* Closure used for either the load report timer or the callback for
* completion of sending the load report. */
grpc_closure client_load_report_closure;
/* Client load report message payload. */
grpc_byte_buffer *client_load_report_payload;
} glb_lb_policy; } glb_lb_policy;
/* Keeps track and reacts to changes in connectivity of the RR instance */ /* Keeps track and reacts to changes in connectivity of the RR instance */
@ -552,8 +595,8 @@ static bool pick_from_internal_rr_locked(
grpc_connected_subchannel **target, wrapped_rr_closure_arg *wc_arg) { grpc_connected_subchannel **target, wrapped_rr_closure_arg *wc_arg) {
GPR_ASSERT(rr_policy != NULL); GPR_ASSERT(rr_policy != NULL);
const bool pick_done = grpc_lb_policy_pick_locked( const bool pick_done = grpc_lb_policy_pick_locked(
exec_ctx, rr_policy, pick_args, target, (void **)&wc_arg->lb_token, exec_ctx, rr_policy, pick_args, target, wc_arg->context,
&wc_arg->wrapper_closure); (void **)&wc_arg->lb_token, &wc_arg->wrapper_closure);
if (pick_done) { if (pick_done) {
/* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */
if (grpc_lb_glb_trace) { if (grpc_lb_glb_trace) {
@ -567,7 +610,12 @@ static bool pick_from_internal_rr_locked(
pick_args->lb_token_mdelem_storage, pick_args->lb_token_mdelem_storage,
GRPC_MDELEM_REF(wc_arg->lb_token)); GRPC_MDELEM_REF(wc_arg->lb_token));
gpr_free(wc_arg); // Pass on client stats via context. Passes ownership of the reference.
GPR_ASSERT(wc_arg->client_stats != NULL);
wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].value = wc_arg->client_stats;
wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].destroy = destroy_client_stats;
gpr_free(wc_arg->free_when_done);
} }
/* else, the pending pick will be registered and taken care of by the /* else, the pending pick will be registered and taken care of by the
* pending pick list inside the RR policy (glb_policy->rr_policy). * pending pick list inside the RR policy (glb_policy->rr_policy).
@ -690,6 +738,8 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
glb_policy->pending_picks = pp->next; glb_policy->pending_picks = pp->next;
GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick"); GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick");
pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy; pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy;
pp->wrapped_on_complete_arg.client_stats =
grpc_grpclb_client_stats_ref(glb_policy->client_stats);
if (grpc_lb_glb_trace) { if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "",
(intptr_t)glb_policy->rr_policy); (intptr_t)glb_policy->rr_policy);
@ -864,9 +914,22 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
grpc_uri_destroy(uri); grpc_uri_destroy(uri);
glb_policy->cc_factory = args->client_channel_factory; glb_policy->cc_factory = args->client_channel_factory;
glb_policy->args = grpc_channel_args_copy(args->args);
GPR_ASSERT(glb_policy->cc_factory != NULL); GPR_ASSERT(glb_policy->cc_factory != NULL);
arg = grpc_channel_args_find(args->args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
glb_policy->lb_call_timeout_ms =
grpc_channel_arg_get_integer(arg, (grpc_integer_options){0, 0, INT_MAX});
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
grpc_arg new_arg;
new_arg.key = GRPC_ARG_LB_POLICY_NAME;
new_arg.type = GRPC_ARG_STRING;
new_arg.value.string = "grpclb";
static const char *args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
glb_policy->args = grpc_channel_args_copy_and_add_and_remove(
args->args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
grpc_slice_hash_table *targets_info = NULL; grpc_slice_hash_table *targets_info = NULL;
/* Create a client channel over them to communicate with a LB service */ /* Create a client channel over them to communicate with a LB service */
char *lb_service_target_addresses = char *lb_service_target_addresses =
@ -880,6 +943,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
grpc_channel_args_destroy(exec_ctx, lb_channel_args); grpc_channel_args_destroy(exec_ctx, lb_channel_args);
gpr_free(lb_service_target_addresses); gpr_free(lb_service_target_addresses);
if (glb_policy->lb_channel == NULL) { if (glb_policy->lb_channel == NULL) {
gpr_free((void *)glb_policy->server_name);
grpc_channel_args_destroy(exec_ctx, glb_policy->args);
gpr_free(glb_policy); gpr_free(glb_policy);
return NULL; return NULL;
} }
@ -895,6 +960,9 @@ static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
GPR_ASSERT(glb_policy->pending_pings == NULL); GPR_ASSERT(glb_policy->pending_pings == NULL);
gpr_free((void *)glb_policy->server_name); gpr_free((void *)glb_policy->server_name);
grpc_channel_args_destroy(exec_ctx, glb_policy->args); grpc_channel_args_destroy(exec_ctx, glb_policy->args);
if (glb_policy->client_stats != NULL) {
grpc_grpclb_client_stats_unref(glb_policy->client_stats);
}
grpc_channel_destroy(glb_policy->lb_channel); grpc_channel_destroy(glb_policy->lb_channel);
glb_policy->lb_channel = NULL; glb_policy->lb_channel = NULL;
grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker); grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker);
@ -1011,7 +1079,8 @@ static void glb_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, void **user_data, grpc_connected_subchannel **target,
grpc_call_context_element *context, void **user_data,
grpc_closure *on_complete) { grpc_closure *on_complete) {
if (pick_args->lb_token_mdelem_storage == NULL) { if (pick_args->lb_token_mdelem_storage == NULL) {
*target = NULL; *target = NULL;
@ -1023,7 +1092,6 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
} }
glb_lb_policy *glb_policy = (glb_lb_policy *)pol; glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
glb_policy->deadline = pick_args->deadline;
bool pick_done; bool pick_done;
if (glb_policy->rr_policy != NULL) { if (glb_policy->rr_policy != NULL) {
@ -1039,6 +1107,10 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_schedule_on_exec_ctx); grpc_schedule_on_exec_ctx);
wc_arg->rr_policy = glb_policy->rr_policy; wc_arg->rr_policy = glb_policy->rr_policy;
wc_arg->target = target; wc_arg->target = target;
wc_arg->context = context;
GPR_ASSERT(glb_policy->client_stats != NULL);
wc_arg->client_stats =
grpc_grpclb_client_stats_ref(glb_policy->client_stats);
wc_arg->wrapped_closure = on_complete; wc_arg->wrapped_closure = on_complete;
wc_arg->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage; wc_arg->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage;
wc_arg->initial_metadata = pick_args->initial_metadata; wc_arg->initial_metadata = pick_args->initial_metadata;
@ -1052,7 +1124,7 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
"picks", "picks",
(void *)(glb_policy)); (void *)(glb_policy));
} }
add_pending_pick(&glb_policy->pending_picks, pick_args, target, add_pending_pick(&glb_policy->pending_picks, pick_args, target, context,
on_complete); on_complete);
if (!glb_policy->started_picking) { if (!glb_policy->started_picking) {
@ -1093,6 +1165,104 @@ static void glb_notify_on_state_change_locked(grpc_exec_ctx *exec_ctx,
exec_ctx, &glb_policy->state_tracker, current, notify); exec_ctx, &glb_policy->state_tracker, current, notify);
} }
static void send_client_load_report_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
static void schedule_next_client_load_report(grpc_exec_ctx *exec_ctx,
glb_lb_policy *glb_policy) {
const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
const gpr_timespec next_client_load_report_time =
gpr_time_add(now, glb_policy->client_stats_report_interval);
grpc_closure_init(&glb_policy->client_load_report_closure,
send_client_load_report_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_timer_init(exec_ctx, &glb_policy->client_load_report_timer,
next_client_load_report_time,
&glb_policy->client_load_report_closure, now);
}
static void client_load_report_done_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
glb_lb_policy *glb_policy = arg;
grpc_byte_buffer_destroy(glb_policy->client_load_report_payload);
glb_policy->client_load_report_payload = NULL;
if (error != GRPC_ERROR_NONE || glb_policy->lb_call == NULL) {
glb_policy->client_load_report_timer_pending = false;
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
"client_load_report");
return;
}
schedule_next_client_load_report(exec_ctx, glb_policy);
}
static void do_send_client_load_report_locked(grpc_exec_ctx *exec_ctx,
glb_lb_policy *glb_policy) {
grpc_op op;
memset(&op, 0, sizeof(op));
op.op = GRPC_OP_SEND_MESSAGE;
op.data.send_message.send_message = glb_policy->client_load_report_payload;
grpc_closure_init(&glb_policy->client_load_report_closure,
client_load_report_done_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_call_error call_error = grpc_call_start_batch_and_execute(
exec_ctx, glb_policy->lb_call, &op, 1,
&glb_policy->client_load_report_closure);
GPR_ASSERT(GRPC_CALL_OK == call_error);
}
static bool load_report_counters_are_zero(grpc_grpclb_request *request) {
return request->client_stats.num_calls_started == 0 &&
request->client_stats.num_calls_finished == 0 &&
request->client_stats.num_calls_finished_with_drop_for_rate_limiting ==
0 &&
request->client_stats
.num_calls_finished_with_drop_for_load_balancing == 0 &&
request->client_stats.num_calls_finished_with_client_failed_to_send ==
0 &&
request->client_stats.num_calls_finished_known_received == 0;
}
static void send_client_load_report_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
glb_lb_policy *glb_policy = arg;
if (error == GRPC_ERROR_CANCELLED || glb_policy->lb_call == NULL) {
glb_policy->client_load_report_timer_pending = false;
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
"client_load_report");
return;
}
// Construct message payload.
GPR_ASSERT(glb_policy->client_load_report_payload == NULL);
grpc_grpclb_request *request =
grpc_grpclb_load_report_request_create(glb_policy->client_stats);
// Skip client load report if the counters were all zero in the last
// report and they are still zero in this one.
if (load_report_counters_are_zero(request)) {
if (glb_policy->last_client_load_report_counters_were_zero) {
grpc_grpclb_request_destroy(request);
schedule_next_client_load_report(exec_ctx, glb_policy);
return;
}
glb_policy->last_client_load_report_counters_were_zero = true;
} else {
glb_policy->last_client_load_report_counters_were_zero = false;
}
grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
glb_policy->client_load_report_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_slice_unref_internal(exec_ctx, request_payload_slice);
grpc_grpclb_request_destroy(request);
// If we've already sent the initial request, then we can go ahead and
// sent the load report. Otherwise, we need to wait until the initial
// request has been sent to send this
// (see lb_on_sent_initial_request_locked() below).
if (glb_policy->initial_request_sent) {
do_send_client_load_report_locked(exec_ctx, glb_policy);
}
}
static void lb_on_sent_initial_request_locked(grpc_exec_ctx *exec_ctx,
void *arg, grpc_error *error);
static void lb_on_server_status_received_locked(grpc_exec_ctx *exec_ctx, static void lb_on_server_status_received_locked(grpc_exec_ctx *exec_ctx,
void *arg, grpc_error *error); void *arg, grpc_error *error);
static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg, static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
@ -1107,13 +1277,24 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
* glb_policy->base.interested_parties, which is comprised of the polling * glb_policy->base.interested_parties, which is comprised of the polling
* entities from \a client_channel. */ * entities from \a client_channel. */
grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name); grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
gpr_timespec deadline =
glb_policy->lb_call_timeout_ms == 0
? gpr_inf_future(GPR_CLOCK_MONOTONIC)
: gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_millis(glb_policy->lb_call_timeout_ms,
GPR_TIMESPAN));
glb_policy->lb_call = grpc_channel_create_pollset_set_call( glb_policy->lb_call = grpc_channel_create_pollset_set_call(
exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS, exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
glb_policy->base.interested_parties, glb_policy->base.interested_parties,
GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD, GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
&host, glb_policy->deadline, NULL); &host, deadline, NULL);
grpc_slice_unref_internal(exec_ctx, host); grpc_slice_unref_internal(exec_ctx, host);
if (glb_policy->client_stats != NULL) {
grpc_grpclb_client_stats_unref(glb_policy->client_stats);
}
glb_policy->client_stats = grpc_grpclb_client_stats_create();
grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv); grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv);
grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv); grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv);
@ -1125,6 +1306,9 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
grpc_slice_unref_internal(exec_ctx, request_payload_slice); grpc_slice_unref_internal(exec_ctx, request_payload_slice);
grpc_grpclb_request_destroy(request); grpc_grpclb_request_destroy(request);
grpc_closure_init(&glb_policy->lb_on_sent_initial_request,
lb_on_sent_initial_request_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_closure_init(&glb_policy->lb_on_server_status_received, grpc_closure_init(&glb_policy->lb_on_server_status_received,
lb_on_server_status_received_locked, glb_policy, lb_on_server_status_received_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false)); grpc_combiner_scheduler(glb_policy->base.combiner, false));
@ -1138,6 +1322,10 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
GRPC_GRPCLB_RECONNECT_JITTER, GRPC_GRPCLB_RECONNECT_JITTER,
GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS * 1000, GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS * 1000,
GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000); GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
glb_policy->initial_request_sent = false;
glb_policy->seen_initial_response = false;
glb_policy->last_client_load_report_counters_were_zero = false;
} }
static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx, static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
@ -1151,6 +1339,10 @@ static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
grpc_byte_buffer_destroy(glb_policy->lb_request_payload); grpc_byte_buffer_destroy(glb_policy->lb_request_payload);
grpc_slice_unref_internal(exec_ctx, glb_policy->lb_call_status_details); grpc_slice_unref_internal(exec_ctx, glb_policy->lb_call_status_details);
if (!glb_policy->client_load_report_timer_pending) {
grpc_timer_cancel(exec_ctx, &glb_policy->client_load_report_timer);
}
} }
/* /*
@ -1179,21 +1371,27 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
op++; op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA; op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata.recv_initial_metadata = op->data.recv_initial_metadata.recv_initial_metadata =
&glb_policy->lb_initial_metadata_recv; &glb_policy->lb_initial_metadata_recv;
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
op++; op++;
GPR_ASSERT(glb_policy->lb_request_payload != NULL); GPR_ASSERT(glb_policy->lb_request_payload != NULL);
op->op = GRPC_OP_SEND_MESSAGE; op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message.send_message = glb_policy->lb_request_payload; op->data.send_message.send_message = glb_policy->lb_request_payload;
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
op++; op++;
/* take a weak ref (won't prevent calling of \a glb_shutdown if the strong ref
* count goes to zero) to be unref'd in lb_on_sent_initial_request_locked() */
GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "lb_on_server_status_received");
call_error = grpc_call_start_batch_and_execute(
exec_ctx, glb_policy->lb_call, ops, (size_t)(op - ops),
&glb_policy->lb_on_sent_initial_request);
GPR_ASSERT(GRPC_CALL_OK == call_error);
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = op->data.recv_status_on_client.trailing_metadata =
&glb_policy->lb_trailing_metadata_recv; &glb_policy->lb_trailing_metadata_recv;
@ -1225,6 +1423,19 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(GRPC_CALL_OK == call_error); GPR_ASSERT(GRPC_CALL_OK == call_error);
} }
static void lb_on_sent_initial_request_locked(grpc_exec_ctx *exec_ctx,
void *arg, grpc_error *error) {
glb_lb_policy *glb_policy = arg;
glb_policy->initial_request_sent = true;
// If we attempted to send a client load report before the initial
// request was sent, send the load report now.
if (glb_policy->client_load_report_payload != NULL) {
do_send_client_load_report_locked(exec_ctx, glb_policy);
}
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
"lb_on_response_received_locked");
}
static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg, static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) { grpc_error *error) {
glb_lb_policy *glb_policy = arg; glb_lb_policy *glb_policy = arg;
@ -1240,11 +1451,41 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_byte_buffer_reader_init(&bbr, glb_policy->lb_response_payload); grpc_byte_buffer_reader_init(&bbr, glb_policy->lb_response_payload);
grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr); grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
grpc_byte_buffer_destroy(glb_policy->lb_response_payload); grpc_byte_buffer_destroy(glb_policy->lb_response_payload);
grpc_grpclb_initial_response *response = NULL;
if (!glb_policy->seen_initial_response &&
(response = grpc_grpclb_initial_response_parse(response_slice)) !=
NULL) {
if (response->has_client_stats_report_interval) {
glb_policy->client_stats_report_interval =
gpr_time_max(gpr_time_from_seconds(1, GPR_TIMESPAN),
grpc_grpclb_duration_to_timespec(
&response->client_stats_report_interval));
if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO,
"received initial LB response message; "
"client load reporting interval = %" PRId64 ".%09d sec",
glb_policy->client_stats_report_interval.tv_sec,
glb_policy->client_stats_report_interval.tv_nsec);
}
/* take a weak ref (won't prevent calling of \a glb_shutdown() if the
* strong ref count goes to zero) to be unref'd in
* send_client_load_report() */
glb_policy->client_load_report_timer_pending = true;
GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "client_load_report");
schedule_next_client_load_report(exec_ctx, glb_policy);
} else if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO,
"received initial LB response message; "
"client load reporting NOT enabled");
}
grpc_grpclb_initial_response_destroy(response);
glb_policy->seen_initial_response = true;
} else {
grpc_grpclb_serverlist *serverlist = grpc_grpclb_serverlist *serverlist =
grpc_grpclb_response_parse_serverlist(response_slice); grpc_grpclb_response_parse_serverlist(response_slice);
if (serverlist != NULL) { if (serverlist != NULL) {
GPR_ASSERT(glb_policy->lb_call != NULL); GPR_ASSERT(glb_policy->lb_call != NULL);
grpc_slice_unref_internal(exec_ctx, response_slice);
if (grpc_lb_glb_trace) { if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, "Serverlist with %lu servers received", gpr_log(GPR_INFO, "Serverlist with %lu servers received",
(unsigned long)serverlist->num_servers); (unsigned long)serverlist->num_servers);
@ -1260,7 +1501,8 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
/* update serverlist */ /* update serverlist */
if (serverlist->num_servers > 0) { if (serverlist->num_servers > 0) {
if (grpc_grpclb_serverlist_equals(glb_policy->serverlist, serverlist)) { if (grpc_grpclb_serverlist_equals(glb_policy->serverlist,
serverlist)) {
if (grpc_lb_glb_trace) { if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"Incoming server list identical to current, ignoring."); "Incoming server list identical to current, ignoring.");
@ -1271,9 +1513,9 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
/* dispose of the old serverlist */ /* dispose of the old serverlist */
grpc_grpclb_destroy_serverlist(glb_policy->serverlist); grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
} }
/* and update the copy in the glb_lb_policy instance. This serverlist /* and update the copy in the glb_lb_policy instance. This
* instance will be destroyed either upon the next update or in * serverlist instance will be destroyed either upon the next
* glb_destroy() */ * update or in glb_destroy() */
glb_policy->serverlist = serverlist; glb_policy->serverlist = serverlist;
rr_handover_locked(exec_ctx, glb_policy); rr_handover_locked(exec_ctx, glb_policy);
@ -1281,16 +1523,18 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
} else { } else {
if (grpc_lb_glb_trace) { if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"Received empty server list. Picks will stay pending until a " "Received empty server list. Picks will stay pending until "
"response with > 0 servers is received"); "a response with > 0 servers is received");
} }
grpc_grpclb_destroy_serverlist(glb_policy->serverlist); grpc_grpclb_destroy_serverlist(serverlist);
} }
} else { /* serverlist == NULL */ } else { /* serverlist == NULL */
gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.", gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.",
grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX)); grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
grpc_slice_unref_internal(exec_ctx, response_slice);
} }
}
grpc_slice_unref_internal(exec_ctx, response_slice);
if (!glb_policy->shutting_down) { if (!glb_policy->shutting_down) {
/* keep listening for serverlist updates */ /* keep listening for serverlist updates */
@ -1403,9 +1647,29 @@ grpc_lb_policy_factory *grpc_glb_lb_factory_create() {
} }
/* Plugin registration */ /* Plugin registration */
// Only add client_load_reporting filter if the grpclb LB policy is used.
static bool maybe_add_client_load_reporting_filter(
grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
const grpc_arg *channel_arg =
grpc_channel_args_find(args, GRPC_ARG_LB_POLICY_NAME);
if (channel_arg != NULL && channel_arg->type == GRPC_ARG_STRING &&
strcmp(channel_arg->value.string, "grpclb") == 0) {
return grpc_channel_stack_builder_append_filter(
builder, (const grpc_channel_filter *)arg, NULL, NULL);
}
return true;
}
void grpc_lb_policy_grpclb_init() { void grpc_lb_policy_grpclb_init() {
grpc_register_lb_policy(grpc_glb_lb_factory_create()); grpc_register_lb_policy(grpc_glb_lb_factory_create());
grpc_register_tracer("glb", &grpc_lb_glb_trace); grpc_register_tracer("glb", &grpc_lb_glb_trace);
grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
maybe_add_client_load_reporting_filter,
(void *)&grpc_client_load_reporting_filter);
} }
void grpc_lb_policy_grpclb_shutdown() {} void grpc_lb_policy_grpclb_shutdown() {}

@ -0,0 +1,133 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
#include "src/core/lib/channel/channel_args.h"
#define GRPC_ARG_GRPCLB_CLIENT_STATS "grpc.grpclb_client_stats"
struct grpc_grpclb_client_stats {
gpr_refcount refs;
gpr_atm num_calls_started;
gpr_atm num_calls_finished;
gpr_atm num_calls_finished_with_drop_for_rate_limiting;
gpr_atm num_calls_finished_with_drop_for_load_balancing;
gpr_atm num_calls_finished_with_client_failed_to_send;
gpr_atm num_calls_finished_known_received;
};
grpc_grpclb_client_stats* grpc_grpclb_client_stats_create() {
grpc_grpclb_client_stats* client_stats = gpr_zalloc(sizeof(*client_stats));
gpr_ref_init(&client_stats->refs, 1);
return client_stats;
}
grpc_grpclb_client_stats* grpc_grpclb_client_stats_ref(
grpc_grpclb_client_stats* client_stats) {
gpr_ref(&client_stats->refs);
return client_stats;
}
void grpc_grpclb_client_stats_unref(grpc_grpclb_client_stats* client_stats) {
if (gpr_unref(&client_stats->refs)) {
gpr_free(client_stats);
}
}
void grpc_grpclb_client_stats_add_call_started(
grpc_grpclb_client_stats* client_stats) {
gpr_atm_full_fetch_add(&client_stats->num_calls_started, (gpr_atm)1);
}
void grpc_grpclb_client_stats_add_call_finished(
bool finished_with_drop_for_rate_limiting,
bool finished_with_drop_for_load_balancing,
bool finished_with_client_failed_to_send, bool finished_known_received,
grpc_grpclb_client_stats* client_stats) {
gpr_atm_full_fetch_add(&client_stats->num_calls_finished, (gpr_atm)1);
if (finished_with_drop_for_rate_limiting) {
gpr_atm_full_fetch_add(
&client_stats->num_calls_finished_with_drop_for_rate_limiting,
(gpr_atm)1);
}
if (finished_with_drop_for_load_balancing) {
gpr_atm_full_fetch_add(
&client_stats->num_calls_finished_with_drop_for_load_balancing,
(gpr_atm)1);
}
if (finished_with_client_failed_to_send) {
gpr_atm_full_fetch_add(
&client_stats->num_calls_finished_with_client_failed_to_send,
(gpr_atm)1);
}
if (finished_known_received) {
gpr_atm_full_fetch_add(&client_stats->num_calls_finished_known_received,
(gpr_atm)1);
}
}
static void atomic_get_and_reset_counter(int64_t* value, gpr_atm* counter) {
*value = (int64_t)gpr_atm_acq_load(counter);
gpr_atm_full_fetch_add(counter, (gpr_atm)(-*value));
}
void grpc_grpclb_client_stats_get(
grpc_grpclb_client_stats* client_stats, int64_t* num_calls_started,
int64_t* num_calls_finished,
int64_t* num_calls_finished_with_drop_for_rate_limiting,
int64_t* num_calls_finished_with_drop_for_load_balancing,
int64_t* num_calls_finished_with_client_failed_to_send,
int64_t* num_calls_finished_known_received) {
atomic_get_and_reset_counter(num_calls_started,
&client_stats->num_calls_started);
atomic_get_and_reset_counter(num_calls_finished,
&client_stats->num_calls_finished);
atomic_get_and_reset_counter(
num_calls_finished_with_drop_for_rate_limiting,
&client_stats->num_calls_finished_with_drop_for_rate_limiting);
atomic_get_and_reset_counter(
num_calls_finished_with_drop_for_load_balancing,
&client_stats->num_calls_finished_with_drop_for_load_balancing);
atomic_get_and_reset_counter(
num_calls_finished_with_client_failed_to_send,
&client_stats->num_calls_finished_with_client_failed_to_send);
atomic_get_and_reset_counter(
num_calls_finished_known_received,
&client_stats->num_calls_finished_known_received);
}

@ -0,0 +1,65 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H
#include <stdbool.h>
#include <grpc/impl/codegen/grpc_types.h>
typedef struct grpc_grpclb_client_stats grpc_grpclb_client_stats;
grpc_grpclb_client_stats* grpc_grpclb_client_stats_create();
grpc_grpclb_client_stats* grpc_grpclb_client_stats_ref(
grpc_grpclb_client_stats* client_stats);
void grpc_grpclb_client_stats_unref(grpc_grpclb_client_stats* client_stats);
void grpc_grpclb_client_stats_add_call_started(
grpc_grpclb_client_stats* client_stats);
void grpc_grpclb_client_stats_add_call_finished(
bool finished_with_drop_for_rate_limiting,
bool finished_with_drop_for_load_balancing,
bool finished_with_client_failed_to_send, bool finished_known_received,
grpc_grpclb_client_stats* client_stats);
void grpc_grpclb_client_stats_get(
grpc_grpclb_client_stats* client_stats, int64_t* num_calls_started,
int64_t* num_calls_finished,
int64_t* num_calls_finished_with_drop_for_rate_limiting,
int64_t* num_calls_finished_with_drop_for_load_balancing,
int64_t* num_calls_finished_with_client_failed_to_send,
int64_t* num_calls_finished_known_received);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H \
*/

@ -80,15 +80,45 @@ static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) { grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) {
grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request)); grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request));
req->has_client_stats = false;
req->has_client_stats = 0; /* TODO(dgq): add support for stats once defined */ req->has_initial_request = true;
req->has_initial_request = 1; req->initial_request.has_name = true;
req->initial_request.has_name = 1;
strncpy(req->initial_request.name, lb_service_name, strncpy(req->initial_request.name, lb_service_name,
GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH); GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
return req; return req;
} }
static void populate_timestamp(gpr_timespec timestamp,
struct _grpc_lb_v1_Timestamp *timestamp_pb) {
timestamp_pb->has_seconds = true;
timestamp_pb->seconds = timestamp.tv_sec;
timestamp_pb->has_nanos = true;
timestamp_pb->nanos = timestamp.tv_nsec;
}
grpc_grpclb_request *grpc_grpclb_load_report_request_create(
grpc_grpclb_client_stats *client_stats) {
grpc_grpclb_request *req = gpr_zalloc(sizeof(grpc_grpclb_request));
req->has_client_stats = true;
req->client_stats.has_timestamp = true;
populate_timestamp(gpr_now(GPR_CLOCK_REALTIME), &req->client_stats.timestamp);
req->client_stats.has_num_calls_started = true;
req->client_stats.has_num_calls_finished = true;
req->client_stats.has_num_calls_finished_with_drop_for_rate_limiting = true;
req->client_stats.has_num_calls_finished_with_drop_for_load_balancing = true;
req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
req->client_stats.has_num_calls_finished_with_client_failed_to_send = true;
req->client_stats.has_num_calls_finished_known_received = true;
grpc_grpclb_client_stats_get(
client_stats, &req->client_stats.num_calls_started,
&req->client_stats.num_calls_finished,
&req->client_stats.num_calls_finished_with_drop_for_rate_limiting,
&req->client_stats.num_calls_finished_with_drop_for_load_balancing,
&req->client_stats.num_calls_finished_with_client_failed_to_send,
&req->client_stats.num_calls_finished_known_received);
return req;
}
grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) { grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
size_t encoded_length; size_t encoded_length;
pb_ostream_t sizestream; pb_ostream_t sizestream;
@ -122,6 +152,9 @@ grpc_grpclb_initial_response *grpc_grpclb_initial_response_parse(
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream)); gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
return NULL; return NULL;
} }
if (!res.has_initial_response) return NULL;
grpc_grpclb_initial_response *initial_res = grpc_grpclb_initial_response *initial_res =
gpr_malloc(sizeof(grpc_grpclb_initial_response)); gpr_malloc(sizeof(grpc_grpclb_initial_response));
memcpy(initial_res, &res.initial_response, memcpy(initial_res, &res.initial_response,
@ -243,6 +276,15 @@ int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs,
return 0; return 0;
} }
gpr_timespec grpc_grpclb_duration_to_timespec(
grpc_grpclb_duration *duration_pb) {
gpr_timespec duration;
duration.tv_sec = duration_pb->has_seconds ? duration_pb->seconds : 0;
duration.tv_nsec = duration_pb->has_nanos ? duration_pb->nanos : 0;
duration.clock_type = GPR_TIMESPAN;
return duration;
}
void grpc_grpclb_initial_response_destroy( void grpc_grpclb_initial_response_destroy(
grpc_grpclb_initial_response *response) { grpc_grpclb_initial_response *response) {
gpr_free(response); gpr_free(response);

@ -36,6 +36,7 @@
#include <grpc/slice_buffer.h> #include <grpc/slice_buffer.h>
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/lb_policy_factory.h"
@ -58,6 +59,8 @@ typedef struct grpc_grpclb_serverlist {
/** Create a request for a gRPC LB service under \a lb_service_name */ /** Create a request for a gRPC LB service under \a lb_service_name */
grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name); grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name);
grpc_grpclb_request *grpc_grpclb_load_report_request_create(
grpc_grpclb_client_stats *client_stats);
/** Protocol Buffers v3-encode \a request */ /** Protocol Buffers v3-encode \a request */
grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request); grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request);
@ -93,6 +96,9 @@ void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist);
int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs, int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs,
const grpc_grpclb_duration *rhs); const grpc_grpclb_duration *rhs);
gpr_timespec grpc_grpclb_duration_to_timespec(
grpc_grpclb_duration *duration_pb);
/** Destroy \a initial_response */ /** Destroy \a initial_response */
void grpc_grpclb_initial_response_destroy( void grpc_grpclb_initial_response_destroy(
grpc_grpclb_initial_response *response); grpc_grpclb_initial_response *response);

@ -189,7 +189,8 @@ static void pf_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
static int pf_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, static int pf_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, void **user_data, grpc_connected_subchannel **target,
grpc_call_context_element *context, void **user_data,
grpc_closure *on_complete) { grpc_closure *on_complete) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol; pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
pending_pick *pp; pending_pick *pp;

@ -414,7 +414,8 @@ static void rr_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
static int rr_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, static int rr_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
const grpc_lb_policy_pick_args *pick_args, const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, void **user_data, grpc_connected_subchannel **target,
grpc_call_context_element *context, void **user_data,
grpc_closure *on_complete) { grpc_closure *on_complete) {
round_robin_lb_policy *p = (round_robin_lb_policy *)pol; round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
pending_pick *pp; pending_pick *pp;

@ -781,7 +781,7 @@ grpc_error *grpc_connected_subchannel_create_call(
(*call)->connection = GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); (*call)->connection = GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
const grpc_call_element_args call_args = {.call_stack = callstk, const grpc_call_element_args call_args = {.call_stack = callstk,
.server_transport_data = NULL, .server_transport_data = NULL,
.context = NULL, .context = args->context,
.path = args->path, .path = args->path,
.start_time = args->start_time, .start_time = args->start_time,
.deadline = args->deadline, .deadline = args->deadline,

@ -119,6 +119,7 @@ typedef struct {
gpr_timespec start_time; gpr_timespec start_time;
gpr_timespec deadline; gpr_timespec deadline;
gpr_arena *arena; gpr_arena *arena;
grpc_call_context_element *context;
} grpc_connected_subchannel_call_args; } grpc_connected_subchannel_call_args;
grpc_error *grpc_connected_subchannel_create_call( grpc_error *grpc_connected_subchannel_create_call(

@ -886,6 +886,10 @@ static bool op_can_be_run(grpc_transport_stream_op_batch *curr_op,
!stream_state->state_op_done[OP_RECV_MESSAGE]) { !stream_state->state_op_done[OP_RECV_MESSAGE]) {
CRONET_LOG(GPR_DEBUG, "Because"); CRONET_LOG(GPR_DEBUG, "Because");
result = false; result = false;
} else if (curr_op->cancel_stream &&
!stream_state->state_callback_received[OP_CANCELED]) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
} else if (curr_op->recv_trailing_metadata) { } else if (curr_op->recv_trailing_metadata) {
/* We aren't done with trailing metadata yet */ /* We aren't done with trailing metadata yet */
if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) { if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {

@ -50,6 +50,9 @@ typedef enum {
/// Reserved for traffic_class_context. /// Reserved for traffic_class_context.
GRPC_CONTEXT_TRAFFIC, GRPC_CONTEXT_TRAFFIC,
/// Value is a \a grpc_grpclb_client_stats.
GRPC_GRPCLB_CLIENT_STATS,
GRPC_CONTEXT_COUNT GRPC_CONTEXT_COUNT
} grpc_context_index; } grpc_context_index;

@ -105,7 +105,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
grpc_error *error) { grpc_error *error) {
grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent, grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent,
req->context->pollset_set); req->context->pollset_set);
grpc_closure_sched(exec_ctx, req->on_done, error); grpc_closure_sched(exec_ctx, req->on_done, GRPC_ERROR_REF(error));
grpc_http_parser_destroy(&req->parser); grpc_http_parser_destroy(&req->parser);
if (req->addresses != NULL) { if (req->addresses != NULL) {
grpc_resolved_addresses_destroy(req->addresses); grpc_resolved_addresses_destroy(req->addresses);

@ -88,6 +88,7 @@
#ifndef __GLIBC__ #ifndef __GLIBC__
#define GRPC_LINUX_EPOLL 1 #define GRPC_LINUX_EPOLL 1
#define GRPC_LINUX_EVENTFD 1 #define GRPC_LINUX_EVENTFD 1
#define GRPC_MSG_IOVLEN_TYPE int
#endif #endif
#ifndef GRPC_LINUX_EVENTFD #ifndef GRPC_LINUX_EVENTFD
#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 #define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1

@ -67,16 +67,16 @@ unsigned gpr_cpu_num_cores(void) {
} }
unsigned gpr_cpu_current_cpu(void) { unsigned gpr_cpu_current_cpu(void) {
#ifdef __GLIBC__ #ifdef GPR_MUSL_LIBC_COMPAT
// sched_getcpu() is undefined on musl
return 0;
#else
int cpu = sched_getcpu(); int cpu = sched_getcpu();
if (cpu < 0) { if (cpu < 0) {
gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno)); gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno));
return 0; return 0;
} }
return (unsigned)cpu; return (unsigned)cpu;
#else
// sched_getcpu() is undefined on musl
return 0;
#endif #endif
} }

@ -31,6 +31,8 @@
* *
*/ */
#include <grpc/support/port_platform.h>
#include <string.h> #include <string.h>
/* Provide a wrapped memcpy for targets that need to be backwards /* Provide a wrapped memcpy for targets that need to be backwards
@ -40,7 +42,7 @@
*/ */
#ifdef __linux__ #ifdef __linux__
#if defined(__x86_64__) && defined(__GNU_LIBRARY__) #if defined(__x86_64__) && !defined(GPR_MUSL_LIBC_COMPAT)
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); __asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *destination, const void *source, size_t num) { void *__wrap_memcpy(void *destination, const void *source, size_t num) {
return memcpy(destination, source, num); return memcpy(destination, source, num);

@ -179,6 +179,9 @@ namespace Grpc.IntegrationTesting
statsResetCount.Increment(); statsResetCount.Increment();
} }
GrpcEnvironment.Logger.Info("[ClientRunnerImpl.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, gen3 {3} (histogram reset count:{4}, seconds since reset: {5})",
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.CollectionCount(3), statsResetCount.Count, secondsElapsed);
// TODO: populate user time and system time // TODO: populate user time and system time
return new ClientStats return new ClientStats
{ {

@ -95,10 +95,13 @@ namespace Grpc.IntegrationTesting
Ports = { new ServerPort(host, options.DriverPort, ServerCredentials.Insecure )} Ports = { new ServerPort(host, options.DriverPort, ServerCredentials.Insecure )}
}; };
int boundPort = server.Ports.Single().BoundPort; int boundPort = server.Ports.Single().BoundPort;
Console.WriteLine("Running qps worker server on " + string.Format("{0}:{1}", host, boundPort)); GrpcEnvironment.Logger.Info("Running qps worker server on {0}:{1}", host, boundPort);
server.Start(); server.Start();
await tcs.Task; await tcs.Task;
await server.ShutdownAsync(); await server.ShutdownAsync();
GrpcEnvironment.Logger.Info("GC collection counts (after shutdown): gen0 {0}, gen1 {1}, gen2 {2}, gen3 {3}",
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.CollectionCount(3));
} }
} }
} }

@ -154,6 +154,9 @@ namespace Grpc.IntegrationTesting
{ {
var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds; var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
GrpcEnvironment.Logger.Info("[ServerRunner.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, gen3 {3} (seconds since last reset {4})",
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.CollectionCount(3), secondsElapsed);
// TODO: populate user time and system time // TODO: populate user time and system time
return new ServerStats return new ServerStats
{ {

@ -42,7 +42,6 @@
#include "call_credentials.h" #include "call_credentials.h"
#include "channel.h" #include "channel.h"
#include "completion_queue.h" #include "completion_queue.h"
#include "completion_queue_async_worker.h"
#include "grpc/grpc.h" #include "grpc/grpc.h"
#include "grpc/grpc_security.h" #include "grpc/grpc_security.h"
#include "grpc/support/alloc.h" #include "grpc/support/alloc.h"

@ -41,7 +41,6 @@
#include "channel.h" #include "channel.h"
#include "channel_credentials.h" #include "channel_credentials.h"
#include "completion_queue.h" #include "completion_queue.h"
#include "completion_queue_async_worker.h"
#include "grpc/grpc.h" #include "grpc/grpc.h"
#include "grpc/grpc_security.h" #include "grpc/grpc_security.h"
#include "timeval.h" #include "timeval.h"

@ -31,8 +31,6 @@
* *
*/ */
#ifdef GRPC_UV
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <node.h> #include <node.h>
#include <uv.h> #include <uv.h>
@ -95,5 +93,3 @@ void CompletionQueueInit(Local<Object> exports) {
} // namespace node } // namespace node
} // namespace grpc } // namespace grpc
#endif /* GRPC_UV */

@ -1,86 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
#define NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
#include <nan.h>
#include "grpc/grpc.h"
namespace grpc {
namespace node {
/* A worker that asynchronously calls completion_queue_next, and queues onto the
node event loop a call to the function stored in the event's tag. */
class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
public:
CompletionQueueAsyncWorker();
~CompletionQueueAsyncWorker();
/* Calls completion_queue_next with the provided deadline, and stores the
event if there was one or sets an error message if there was not */
void Execute();
/* Returns the completion queue attached to this class */
static grpc_completion_queue *GetQueue();
/* Convenience function to create a worker with the given arguments and queue
it to run asynchronously */
static void Next();
/* Initialize the CompletionQueueAsyncWorker class */
static void Init(v8::Local<v8::Object> exports);
protected:
/* Called when Execute has succeeded (completed without setting an error
message). Calls the saved callback with the event that came from
completion_queue_next */
void HandleOKCallback();
void HandleErrorCallback();
private:
grpc_event result;
static grpc_completion_queue *queue;
// Number of grpc_completion_queue_next calls in the thread pool
static int current_threads;
// Number of grpc_completion_queue_next calls waiting to enter the thread pool
static int waiting_next_calls;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_

@ -1,180 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* I don't like using #ifndef, but I don't see a better way to do this */
#ifndef GRPC_UV
#include <nan.h>
#include <node.h>
#include "call.h"
#include "completion_queue.h"
#include "grpc/grpc.h"
#include "grpc/support/log.h"
#include "grpc/support/time.h"
namespace grpc {
namespace node {
namespace {
/* A worker that asynchronously calls completion_queue_next, and queues onto the
node event loop a call to the function stored in the event's tag. */
class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
public:
CompletionQueueAsyncWorker();
~CompletionQueueAsyncWorker();
/* Calls completion_queue_next with the provided deadline, and stores the
event if there was one or sets an error message if there was not */
void Execute();
/* Returns the completion queue attached to this class */
static grpc_completion_queue *GetQueue();
/* Convenience function to create a worker with the given arguments and queue
it to run asynchronously */
static void Next();
/* Initialize the CompletionQueueAsyncWorker class */
static void Init(v8::Local<v8::Object> exports);
protected:
/* Called when Execute has succeeded (completed without setting an error
message). Calls the saved callback with the event that came from
completion_queue_next */
void HandleOKCallback();
void HandleErrorCallback();
private:
static void TryAddWorker();
grpc_event result;
static grpc_completion_queue *queue;
// Number of grpc_completion_queue_next calls in the thread pool
static int current_threads;
// Number of grpc_completion_queue_next calls waiting to enter the thread pool
static int waiting_next_calls;
};
const int max_queue_threads = 2;
using v8::Function;
using v8::Local;
using v8::Object;
using v8::Value;
grpc_completion_queue *CompletionQueueAsyncWorker::queue;
// Invariants: current_threads <= max_queue_threads
// (current_threads == max_queue_threads) || (waiting_next_calls == 0)
int CompletionQueueAsyncWorker::current_threads;
int CompletionQueueAsyncWorker::waiting_next_calls;
CompletionQueueAsyncWorker::CompletionQueueAsyncWorker()
: Nan::AsyncWorker(NULL) {}
CompletionQueueAsyncWorker::~CompletionQueueAsyncWorker() {}
void CompletionQueueAsyncWorker::Execute() {
result = grpc_completion_queue_next(queue, gpr_inf_future(GPR_CLOCK_REALTIME),
NULL);
if (!result.success) {
SetErrorMessage("The async function encountered an error");
}
}
grpc_completion_queue *CompletionQueueAsyncWorker::GetQueue() { return queue; }
void CompletionQueueAsyncWorker::TryAddWorker() {
if (current_threads < max_queue_threads && waiting_next_calls > 0) {
current_threads += 1;
waiting_next_calls -= 1;
CompletionQueueAsyncWorker *worker = new CompletionQueueAsyncWorker();
Nan::AsyncQueueWorker(worker);
}
GPR_ASSERT(current_threads <= max_queue_threads);
GPR_ASSERT((current_threads == max_queue_threads) ||
(waiting_next_calls == 0));
}
void CompletionQueueAsyncWorker::Next() {
waiting_next_calls += 1;
TryAddWorker();
}
void CompletionQueueAsyncWorker::Init(Local<Object> exports) {
Nan::HandleScope scope;
current_threads = 0;
waiting_next_calls = 0;
queue = grpc_completion_queue_create_for_next(NULL);
}
void CompletionQueueAsyncWorker::HandleOKCallback() {
Nan::HandleScope scope;
current_threads -= 1;
TryAddWorker();
CompleteTag(result.tag, NULL);
DestroyTag(result.tag);
}
void CompletionQueueAsyncWorker::HandleErrorCallback() {
Nan::HandleScope scope;
current_threads -= 1;
TryAddWorker();
CompleteTag(result.tag, ErrorMessage());
DestroyTag(result.tag);
}
} // namespace
grpc_completion_queue *GetCompletionQueue() {
return CompletionQueueAsyncWorker::GetQueue();
}
void CompletionQueueNext() { CompletionQueueAsyncWorker::Next(); }
void CompletionQueueInit(Local<Object> exports) {
CompletionQueueAsyncWorker::Init(exports);
}
} // namespace node
} // namespace grpc
#endif /* GRPC_UV */

@ -43,18 +43,15 @@
#include "grpc/support/time.h" #include "grpc/support/time.h"
// TODO(murgatroid99): Remove this when the endpoint API becomes public // TODO(murgatroid99): Remove this when the endpoint API becomes public
#ifdef GRPC_UV
extern "C" { extern "C" {
#include "src/core/lib/iomgr/pollset_uv.h" #include "src/core/lib/iomgr/pollset_uv.h"
} }
#endif
#include "call.h" #include "call.h"
#include "call_credentials.h" #include "call_credentials.h"
#include "channel.h" #include "channel.h"
#include "channel_credentials.h" #include "channel_credentials.h"
#include "completion_queue.h" #include "completion_queue.h"
#include "completion_queue_async_worker.h"
#include "server.h" #include "server.h"
#include "server_credentials.h" #include "server_credentials.h"
#include "slice.h" #include "slice.h"
@ -432,9 +429,7 @@ void init(Local<Object> exports) {
InitWriteFlags(exports); InitWriteFlags(exports);
InitLogConstants(exports); InitLogConstants(exports);
#ifdef GRPC_UV
grpc_pollset_work_run_loop = 0; grpc_pollset_work_run_loop = 0;
#endif
grpc::node::Call::Init(exports); grpc::node::Call::Init(exports);
grpc::node::CallCredentials::Init(exports); grpc::node::CallCredentials::Init(exports);

@ -41,7 +41,6 @@
#include <vector> #include <vector>
#include "call.h" #include "call.h"
#include "completion_queue.h" #include "completion_queue.h"
#include "completion_queue_async_worker.h"
#include "grpc/grpc.h" #include "grpc/grpc.h"
#include "grpc/grpc_security.h" #include "grpc/grpc_security.h"
#include "grpc/support/log.h" #include "grpc/support/log.h"
@ -78,6 +77,30 @@ using v8::Value;
Nan::Callback *Server::constructor; Nan::Callback *Server::constructor;
Persistent<FunctionTemplate> Server::fun_tpl; Persistent<FunctionTemplate> Server::fun_tpl;
static Callback *shutdown_callback = NULL;
class ServerShutdownOp : public Op {
public:
ServerShutdownOp(grpc_server *server) : server(server) {}
~ServerShutdownOp() {}
Local<Value> GetNodeValue() const { return Nan::Null(); }
bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
bool IsFinalOp() { return false; }
void OnComplete(bool success) {
/* Because cancel_all_calls was called, we assume that shutdown_and_notify
completes successfully */
grpc_server_destroy(server);
}
grpc_server *server;
protected:
std::string GetTypeString() const { return "shutdown"; }
};
class NewCallOp : public Op { class NewCallOp : public Op {
public: public:
NewCallOp() { NewCallOp() {
@ -149,6 +172,10 @@ class TryShutdownOp : public Op {
server_persist; server_persist;
}; };
Server::Server(grpc_server *server) : wrapped_server(server) {}
Server::~Server() { this->ShutdownServer(); }
void Server::Init(Local<Object> exports) { void Server::Init(Local<Object> exports) {
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New); Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
@ -177,6 +204,36 @@ void Server::DestroyWrappedServer() {
} }
} }
NAN_METHOD(ServerShutdownCallback) {
if (!info[0]->IsNull()) {
return Nan::ThrowError("forceShutdown failed somehow");
}
}
void Server::ShutdownServer() {
Nan::HandleScope scope;
if (this->wrapped_server != NULL) {
if (shutdown_callback == NULL) {
Local<FunctionTemplate> callback_tpl =
Nan::New<FunctionTemplate>(ServerShutdownCallback);
shutdown_callback =
new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
}
ServerShutdownOp *op = new ServerShutdownOp(this->wrapped_server);
unique_ptr<OpVec> ops(new OpVec());
ops->push_back(unique_ptr<Op>(op));
grpc_server_shutdown_and_notify(
this->wrapped_server, GetCompletionQueue(),
new struct tag(new Callback(**shutdown_callback), ops.release(), NULL,
Nan::Null()));
grpc_server_cancel_all_calls(this->wrapped_server);
CompletionQueueNext();
this->wrapped_server = NULL;
}
}
NAN_METHOD(Server::New) { NAN_METHOD(Server::New) {
/* If this is not a constructor call, make a constructor call and return /* If this is not a constructor call, make a constructor call and return
the result */ the result */

@ -1,120 +0,0 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifdef GRPC_UV
#include "server.h"
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
#include "grpc/support/time.h"
#include "call.h"
#include "completion_queue.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::MaybeLocal;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Object;
using v8::Value;
static Callback *shutdown_callback = NULL;
class ServerShutdownOp : public Op {
public:
ServerShutdownOp(grpc_server *server) : server(server) {}
~ServerShutdownOp() {}
Local<Value> GetNodeValue() const { return Nan::Null(); }
bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
bool IsFinalOp() { return false; }
void OnComplete(bool success) {
/* Because cancel_all_calls was called, we assume that shutdown_and_notify
completes successfully */
grpc_server_destroy(server);
}
grpc_server *server;
protected:
std::string GetTypeString() const { return "shutdown"; }
};
Server::Server(grpc_server *server) : wrapped_server(server) {}
Server::~Server() { this->ShutdownServer(); }
NAN_METHOD(ServerShutdownCallback) {
if (!info[0]->IsNull()) {
return Nan::ThrowError("forceShutdown failed somehow");
}
}
void Server::ShutdownServer() {
Nan::HandleScope scope;
if (this->wrapped_server != NULL) {
if (shutdown_callback == NULL) {
Local<FunctionTemplate> callback_tpl =
Nan::New<FunctionTemplate>(ServerShutdownCallback);
shutdown_callback =
new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
}
ServerShutdownOp *op = new ServerShutdownOp(this->wrapped_server);
unique_ptr<OpVec> ops(new OpVec());
ops->push_back(unique_ptr<Op>(op));
grpc_server_shutdown_and_notify(
this->wrapped_server, GetCompletionQueue(),
new struct tag(new Callback(**shutdown_callback), ops.release(), NULL,
Nan::Null()));
grpc_server_cancel_all_calls(this->wrapped_server);
CompletionQueueNext();
this->wrapped_server = NULL;
}
}
} // namespace grpc
} // namespace node
#endif /* GRPC_UV */

@ -1,4 +1,3 @@
#!/bin/bash
# Copyright 2017, Google Inc. # Copyright 2017, Google Inc.
# All rights reserved. # All rights reserved.
# #
@ -28,13 +27,13 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex licenses(["notice"]) # 3-clause BSD
# change to grpc repo root package(default_visibility = ["//visibility:public"])
cd $(dirname $0)/../../..
git submodule update --init load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
# download fuzzer docker image from dockerhub grpc_proto_library(
export DOCKERHUB_ORGANIZATION=grpctesting name = "load_balancer_proto",
config=asan-trace-cmp tools/jenkins/run_fuzzer.sh uri_fuzzer_test srcs = ["load_balancer.proto"],
)

@ -37,9 +37,16 @@ cdef int _INTERRUPT_CHECK_PERIOD_MS = 200
cdef class CompletionQueue: cdef class CompletionQueue:
def __cinit__(self): def __cinit__(self, shutdown_cq=False):
cdef grpc_completion_queue_attributes c_attrs
grpc_init() grpc_init()
with nogil: if shutdown_cq:
c_attrs.version = 1
c_attrs.cq_completion_type = GRPC_CQ_NEXT
c_attrs.cq_polling_type = GRPC_CQ_NON_LISTENING
self.c_completion_queue = grpc_completion_queue_create(
grpc_completion_queue_factory_lookup(&c_attrs), &c_attrs, NULL);
else:
self.c_completion_queue = grpc_completion_queue_create_for_next(NULL) self.c_completion_queue = grpc_completion_queue_create_for_next(NULL)
self.is_shutting_down = False self.is_shutting_down = False
self.is_shutdown = False self.is_shutdown = False

@ -217,6 +217,20 @@ cdef extern from "grpc/grpc.h":
GRPC_CALL_ERROR_INVALID_FLAGS GRPC_CALL_ERROR_INVALID_FLAGS
GRPC_CALL_ERROR_INVALID_METADATA GRPC_CALL_ERROR_INVALID_METADATA
ctypedef enum grpc_cq_completion_type:
GRPC_CQ_NEXT
GRPC_CQ_PLUCK
ctypedef enum grpc_cq_polling_type:
GRPC_CQ_DEFAULT_POLLING
GRPC_CQ_NON_LISTENING
GRPC_CQ_NON_POLLING
ctypedef struct grpc_completion_queue_attributes:
int version
grpc_cq_completion_type cq_completion_type
grpc_cq_polling_type cq_polling_type
ctypedef enum grpc_connectivity_state: ctypedef enum grpc_connectivity_state:
GRPC_CHANNEL_IDLE GRPC_CHANNEL_IDLE
GRPC_CHANNEL_CONNECTING GRPC_CHANNEL_CONNECTING
@ -309,6 +323,14 @@ cdef extern from "grpc/grpc.h":
void grpc_init() nogil void grpc_init() nogil
void grpc_shutdown() nogil void grpc_shutdown() nogil
ctypedef struct grpc_completion_queue_factory:
pass
grpc_completion_queue_factory *grpc_completion_queue_factory_lookup(
const grpc_completion_queue_attributes* attributes) nogil
grpc_completion_queue *grpc_completion_queue_create(
const grpc_completion_queue_factory* factory,
const grpc_completion_queue_attributes* attr, void* reserved) nogil
grpc_completion_queue *grpc_completion_queue_create_for_next(void *reserved) nogil grpc_completion_queue *grpc_completion_queue_create_for_next(void *reserved) nogil
grpc_event grpc_completion_queue_next(grpc_completion_queue *cq, grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,

@ -85,7 +85,7 @@ cdef class Server:
def start(self): def start(self):
if self.is_started: if self.is_started:
raise ValueError("the server has already started") raise ValueError("the server has already started")
self.backup_shutdown_queue = CompletionQueue() self.backup_shutdown_queue = CompletionQueue(shutdown_cq=True)
self.register_completion_queue(self.backup_shutdown_queue) self.register_completion_queue(self.backup_shutdown_queue)
self.is_started = True self.is_started = True
with nogil: with nogil:

@ -280,8 +280,10 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c', 'third_party/nanopb/pb_common.c',

@ -29,7 +29,6 @@
"""Setup module for the GRPC Python package's optional health checking.""" """Setup module for the GRPC Python package's optional health checking."""
import os import os
import sys
import setuptools import setuptools

@ -41,15 +41,16 @@
{ {
'variables': { 'variables': {
'runtime%': 'node', 'runtime%': 'node',
# UV integration in C core is enabled by default. It can be disabled
# by setting this argument to anything else.
'grpc_uv%': 'true',
# Some Node installations use the system installation of OpenSSL, and on # Some Node installations use the system installation of OpenSSL, and on
# some systems, the system OpenSSL still does not have ALPN support. This # some systems, the system OpenSSL still does not have ALPN support. This
# will let users recompile gRPC to work without ALPN. # will let users recompile gRPC to work without ALPN.
'grpc_alpn%': 'true', 'grpc_alpn%': 'true',
# Indicates that the library should be built with gcov. # Indicates that the library should be built with gcov.
'grpc_gcov%': 'false' 'grpc_gcov%': 'false',
# Indicates that the library should be built with compatibility for musl
# libc, so that it can run on Alpine Linux. This is only necessary if not
# building on Alpine Linux
'grpc_alpine%': 'false'
}, },
'target_defaults': { 'target_defaults': {
'configurations': { 'configurations': {
@ -83,17 +84,11 @@
'include' 'include'
], ],
'defines': [ 'defines': [
'GPR_BACKWARDS_COMPATIBILITY_MODE' 'GPR_BACKWARDS_COMPATIBILITY_MODE',
],
'conditions': [
['grpc_uv=="true"', {
'defines': [
'GRPC_ARES=0', 'GRPC_ARES=0',
# Disabling this while bugs are ironed out. Uncomment this to
# re-enable libuv integration in C core.
'GRPC_UV' 'GRPC_UV'
] ],
}], 'conditions': [
['grpc_gcov=="true"', { ['grpc_gcov=="true"', {
% for arg, prop in [('CPPFLAGS', 'cflags'), ('DEFINES', 'defines'), ('LDFLAGS', 'ldflags')]: % for arg, prop in [('CPPFLAGS', 'cflags'), ('DEFINES', 'defines'), ('LDFLAGS', 'ldflags')]:
% if configs['gcov'].get(arg, None) is not None: % if configs['gcov'].get(arg, None) is not None:
@ -105,6 +100,11 @@
% endif % endif
% endfor % endfor
}], }],
['grpc_alpine=="true"', {
'defines': [
'GPR_MUSL_LIBC_COMPAT'
]
}],
['OS!="win" and runtime=="electron"', { ['OS!="win" and runtime=="electron"', {
"defines": [ "defines": [
'OPENSSL_NO_THREADS' 'OPENSSL_NO_THREADS'
@ -233,6 +233,10 @@
} }
] ]
}, },
]
}],
['OS == "win"', {
'targets': [
# Only want to compile zlib under Windows # Only want to compile zlib under Windows
% for module in node_modules: % for module in node_modules:
% for lib in libs: % for lib in libs:
@ -264,13 +268,6 @@
}] }]
], ],
'targets': [ 'targets': [
<%
for lib in libs:
if 'grpc' in lib.transitive_deps or lib.name == 'grpc':
lib.deps.append('node_modules/cares/deps/cares/cares.gyp:cares')
for module in node_modules:
module.deps.append('node_modules/cares/deps/cares/cares.gyp:cares')
%>
% for module in node_modules: % for module in node_modules:
% for lib in libs: % for lib in libs:
% if lib.name in module.transitive_deps and lib.name not in ('boringssl', 'z'): % if lib.name in module.transitive_deps and lib.name not in ('boringssl', 'z'):

@ -36,8 +36,7 @@
"lodash": "^4.15.0", "lodash": "^4.15.0",
"nan": "^2.0.0", "nan": "^2.0.0",
"node-pre-gyp": "^0.6.0", "node-pre-gyp": "^0.6.0",
"protobufjs": "^6.7.0", "protobufjs": "^6.7.0"
"cares": "^1.1.5"
}, },
"devDependencies": { "devDependencies": {
"async": "^2.0.1", "async": "^2.0.1",

@ -189,23 +189,6 @@ int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str) {
return res; return res;
} }
static void verify_matches(expectation *e, grpc_event *ev) {
GPR_ASSERT(e->type == ev->type);
switch (e->type) {
case GRPC_QUEUE_SHUTDOWN:
gpr_log(GPR_ERROR, "premature queue shutdown");
abort();
break;
case GRPC_OP_COMPLETE:
GPR_ASSERT(e->success == ev->success);
break;
case GRPC_QUEUE_TIMEOUT:
gpr_log(GPR_ERROR, "not implemented");
abort();
break;
}
}
static void expectation_to_strvec(gpr_strvec *buf, expectation *e) { static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
char *tmp; char *tmp;
@ -214,7 +197,7 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
switch (e->type) { switch (e->type) {
case GRPC_OP_COMPLETE: case GRPC_OP_COMPLETE:
gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d %s:%d", e->success, gpr_asprintf(&tmp, "GRPC_OP_COMPLETE success=%d %s:%d", e->success,
e->file, e->line); e->file, e->line);
gpr_strvec_add(buf, tmp); gpr_strvec_add(buf, tmp);
break; break;
@ -248,6 +231,32 @@ static void fail_no_event_received(cq_verifier *v) {
abort(); abort();
} }
static void verify_matches(expectation *e, grpc_event *ev) {
GPR_ASSERT(e->type == ev->type);
switch (e->type) {
case GRPC_OP_COMPLETE:
if (e->success != ev->success) {
gpr_strvec expected;
gpr_strvec_init(&expected);
expectation_to_strvec(&expected, e);
char *s = gpr_strvec_flatten(&expected, NULL);
gpr_strvec_destroy(&expected);
gpr_log(GPR_ERROR, "actual success does not match expected: %s", s);
gpr_free(s);
abort();
}
break;
case GRPC_QUEUE_SHUTDOWN:
gpr_log(GPR_ERROR, "premature queue shutdown");
abort();
break;
case GRPC_QUEUE_TIMEOUT:
gpr_log(GPR_ERROR, "not implemented");
abort();
break;
}
}
void cq_verify(cq_verifier *v) { void cq_verify(cq_verifier *v) {
const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
while (v->first_expectation != NULL) { while (v->first_expectation != NULL) {

@ -56,9 +56,6 @@
#include "test/core/end2end/fake_resolver.h" #include "test/core/end2end/fake_resolver.h"
#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
"grpc.fake_resolver.response_generator"
// //
// fake_resolver // fake_resolver
// //

@ -38,6 +38,9 @@
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"
#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
"grpc.fake_resolver.response_generator"
void grpc_fake_resolver_init(); void grpc_fake_resolver_init();
// Instances of \a grpc_fake_resolver_response_generator are passed to the // Instances of \a grpc_fake_resolver_response_generator are passed to the

@ -115,8 +115,8 @@ void test_slice_buffer_move_first() {
grpc_slice_buffer_move_first(&src, 2, &dst); grpc_slice_buffer_move_first(&src, 2, &dst);
src_len -= 2; src_len -= 2;
dst_len += 2; dst_len += 2;
GPR_ASSERT(src.length == src.length); GPR_ASSERT(src.length == src_len);
GPR_ASSERT(dst.length == dst.length); GPR_ASSERT(dst.length == dst_len);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {

@ -50,6 +50,10 @@ TEST_F(CredentialsTest, InvalidGoogleRefreshToken) {
EXPECT_EQ(static_cast<CallCredentials*>(nullptr), bad1.get()); EXPECT_EQ(static_cast<CallCredentials*>(nullptr), bad1.get());
} }
TEST_F(CredentialsTest, DefaultCredentials) {
auto creds = GoogleDefaultCredentials();
}
} // namespace testing } // namespace testing
} // namespace grpc } // namespace grpc

@ -69,6 +69,9 @@ namespace testing {
// ServiceA leading comment 1 // ServiceA leading comment 1
class ServiceA final { class ServiceA final {
public: public:
static constexpr char const* service_full_name() {
return "grpc.testing.ServiceA";
}
class StubInterface { class StubInterface {
public: public:
virtual ~StubInterface() {} virtual ~StubInterface() {}
@ -373,6 +376,9 @@ class ServiceA final {
// ServiceB leading comment 1 // ServiceB leading comment 1
class ServiceB final { class ServiceB final {
public: public:
static constexpr char const* service_full_name() {
return "grpc.testing.ServiceB";
}
class StubInterface { class StubInterface {
public: public:
virtual ~StubInterface() {} virtual ~StubInterface() {}

@ -48,10 +48,10 @@ cc_test(
"//:grpc", "//:grpc",
"//:grpc++", "//:grpc++",
"//external:gtest", "//external:gtest",
"//src/proto/grpc/health/v1:health_proto",
"//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
"//src/proto/grpc/health/v1:health_proto",
"//test/core/util:gpr_test_util", "//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util", "//test/core/util:grpc_test_util",
"//test/cpp/util:test_util", "//test/cpp/util:test_util",
@ -198,6 +198,27 @@ cc_test(
], ],
) )
cc_test(
name = "grpclb_end2end_test",
srcs = ["grpclb_end2end_test.cc"],
deps = [
":test_service_impl",
"//:gpr",
"//:grpc",
"//:grpc++",
"//external:gtest",
"//src/proto/grpc/lb/v1:load_balancer_proto",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
"//test/core/end2end:fake_resolver",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
"//test/cpp/util:test_util",
],
)
cc_test( cc_test(
name = "proto_server_reflection_test", name = "proto_server_reflection_test",
srcs = ["proto_server_reflection_test.cc"], srcs = ["proto_server_reflection_test.cc"],

@ -0,0 +1,639 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <memory>
#include <mutex>
#include <sstream>
#include <thread>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <gtest/gtest.h>
extern "C" {
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/end2end/fake_resolver.h"
}
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
// TODO(dgq): Other scenarios in need of testing:
// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc).
// - Test reception of invalid serverlist
// - Test pinging
// - Test against a non-LB server.
// - Random LB server closing the stream unexpectedly.
// - Test using DNS-resolvable names (localhost?)
// - Test handling of creation of faulty RR instance by having the LB return a
// serverlist with non-existent backends after having initially returned a
// valid one.
//
// Findings from end to end testing to be covered here:
// - Handling of LB servers restart, including reconnection after backing-off
// retries.
// - Destruction of load balanced channel (and therefore of grpclb instance)
// while:
// 1) the internal LB call is still active. This should work by virtue
// of the weak reference the LB call holds. The call should be terminated as
// part of the grpclb shutdown process.
// 2) the retry timer is active. Again, the weak reference it holds should
// prevent a premature call to \a glb_destroy.
// - Restart of backend servers with no changes to serverlist. This exercises
// the RR handover mechanism.
using std::chrono::system_clock;
using grpc::lb::v1::LoadBalanceResponse;
using grpc::lb::v1::LoadBalanceRequest;
using grpc::lb::v1::LoadBalancer;
namespace grpc {
namespace testing {
namespace {
template <typename ServiceType>
class CountedService : public ServiceType {
public:
int request_count() {
std::unique_lock<std::mutex> lock(mu_);
return request_count_;
}
int response_count() {
std::unique_lock<std::mutex> lock(mu_);
return response_count_;
}
void IncreaseResponseCount() {
std::unique_lock<std::mutex> lock(mu_);
++response_count_;
}
void IncreaseRequestCount() {
std::unique_lock<std::mutex> lock(mu_);
++request_count_;
}
protected:
std::mutex mu_;
private:
int request_count_ = 0;
int response_count_ = 0;
};
using BackendService = CountedService<TestServiceImpl>;
using BalancerService = CountedService<LoadBalancer::Service>;
class BackendServiceImpl : public BackendService {
public:
BackendServiceImpl() {}
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) override {
IncreaseRequestCount();
const auto status = TestServiceImpl::Echo(context, request, response);
IncreaseResponseCount();
return status;
}
};
grpc::string Ip4ToPackedString(const char* ip_str) {
struct in_addr ip4;
GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1);
return grpc::string(reinterpret_cast<const char*>(&ip4), sizeof(ip4));
}
struct ClientStats {
size_t num_calls_started = 0;
size_t num_calls_finished = 0;
size_t num_calls_finished_with_drop_for_rate_limiting = 0;
size_t num_calls_finished_with_drop_for_load_balancing = 0;
size_t num_calls_finished_with_client_failed_to_send = 0;
size_t num_calls_finished_known_received = 0;
ClientStats& operator+=(const ClientStats& other) {
num_calls_started += other.num_calls_started;
num_calls_finished += other.num_calls_finished;
num_calls_finished_with_drop_for_rate_limiting +=
other.num_calls_finished_with_drop_for_rate_limiting;
num_calls_finished_with_drop_for_load_balancing +=
other.num_calls_finished_with_drop_for_load_balancing;
num_calls_finished_with_client_failed_to_send +=
other.num_calls_finished_with_client_failed_to_send;
num_calls_finished_known_received +=
other.num_calls_finished_known_received;
return *this;
}
};
class BalancerServiceImpl : public BalancerService {
public:
using Stream = ServerReaderWriter<LoadBalanceResponse, LoadBalanceRequest>;
using ResponseDelayPair = std::pair<LoadBalanceResponse, int>;
explicit BalancerServiceImpl(int client_load_reporting_interval_seconds)
: client_load_reporting_interval_seconds_(
client_load_reporting_interval_seconds),
shutdown_(false) {}
Status BalanceLoad(ServerContext* context, Stream* stream) override {
LoadBalanceRequest request;
stream->Read(&request);
IncreaseRequestCount();
gpr_log(GPR_INFO, "LB: recv msg '%s'", request.DebugString().c_str());
if (client_load_reporting_interval_seconds_ > 0) {
LoadBalanceResponse initial_response;
initial_response.mutable_initial_response()
->mutable_client_stats_report_interval()
->set_seconds(client_load_reporting_interval_seconds_);
stream->Write(initial_response);
}
std::vector<ResponseDelayPair> responses_and_delays;
{
std::unique_lock<std::mutex> lock(mu_);
responses_and_delays = responses_and_delays_;
}
for (const auto& response_and_delay : responses_and_delays) {
if (shutdown_) break;
SendResponse(stream, response_and_delay.first, response_and_delay.second);
}
if (client_load_reporting_interval_seconds_ > 0) {
request.Clear();
stream->Read(&request);
gpr_log(GPR_INFO, "LB: recv client load report msg: '%s'",
request.DebugString().c_str());
GPR_ASSERT(request.has_client_stats());
client_stats_.num_calls_started +=
request.client_stats().num_calls_started();
client_stats_.num_calls_finished +=
request.client_stats().num_calls_finished();
client_stats_.num_calls_finished_with_drop_for_rate_limiting +=
request.client_stats()
.num_calls_finished_with_drop_for_rate_limiting();
client_stats_.num_calls_finished_with_drop_for_load_balancing +=
request.client_stats()
.num_calls_finished_with_drop_for_load_balancing();
client_stats_.num_calls_finished_with_client_failed_to_send +=
request.client_stats()
.num_calls_finished_with_client_failed_to_send();
client_stats_.num_calls_finished_known_received +=
request.client_stats().num_calls_finished_known_received();
std::lock_guard<std::mutex> lock(mu_);
cond_.notify_one();
}
return Status::OK;
}
void add_response(const LoadBalanceResponse& response, int send_after_ms) {
std::unique_lock<std::mutex> lock(mu_);
responses_and_delays_.push_back(std::make_pair(response, send_after_ms));
}
void Shutdown() {
std::unique_lock<std::mutex> lock(mu_);
shutdown_ = true;
}
static LoadBalanceResponse BuildResponseForBackends(
const std::vector<int>& backend_ports) {
LoadBalanceResponse response;
for (const int backend_port : backend_ports) {
auto* server = response.mutable_server_list()->add_servers();
server->set_ip_address(Ip4ToPackedString("127.0.0.1"));
server->set_port(backend_port);
}
return response;
}
const ClientStats& WaitForLoadReport() {
std::unique_lock<std::mutex> lock(mu_);
cond_.wait(lock);
return client_stats_;
}
private:
void SendResponse(Stream* stream, const LoadBalanceResponse& response,
int delay_ms) {
gpr_log(GPR_INFO, "LB: sleeping for %d ms...", delay_ms);
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_millis(delay_ms, GPR_TIMESPAN)));
gpr_log(GPR_INFO, "LB: Woke up! Sending response '%s'",
response.DebugString().c_str());
stream->Write(response);
IncreaseResponseCount();
}
const int client_load_reporting_interval_seconds_;
std::vector<ResponseDelayPair> responses_and_delays_;
std::mutex mu_;
std::condition_variable cond_;
ClientStats client_stats_;
bool shutdown_;
};
class GrpclbEnd2endTest : public ::testing::Test {
protected:
GrpclbEnd2endTest(int num_backends, int num_balancers,
int client_load_reporting_interval_seconds)
: server_host_("localhost"),
num_backends_(num_backends),
num_balancers_(num_balancers),
client_load_reporting_interval_seconds_(
client_load_reporting_interval_seconds) {}
void SetUp() override {
response_generator_ = grpc_fake_resolver_response_generator_create();
// Start the backends.
for (size_t i = 0; i < num_backends_; ++i) {
backends_.emplace_back(new BackendServiceImpl());
backend_servers_.emplace_back(ServerThread<BackendService>(
"backend", server_host_, backends_.back().get()));
}
// Start the load balancers.
for (size_t i = 0; i < num_balancers_; ++i) {
balancers_.emplace_back(
new BalancerServiceImpl(client_load_reporting_interval_seconds_));
balancer_servers_.emplace_back(ServerThread<BalancerService>(
"balancer", server_host_, balancers_.back().get()));
}
ResetStub();
std::vector<AddressData> addresses;
for (size_t i = 0; i < balancer_servers_.size(); ++i) {
addresses.emplace_back(AddressData{balancer_servers_[i].port_, true, ""});
}
SetNextResolution(addresses);
}
void TearDown() override {
for (size_t i = 0; i < backends_.size(); ++i) {
backend_servers_[i].Shutdown();
}
for (size_t i = 0; i < balancers_.size(); ++i) {
balancers_[i]->Shutdown();
balancer_servers_[i].Shutdown();
}
grpc_fake_resolver_response_generator_unref(response_generator_);
}
void ResetStub() {
ChannelArguments args;
args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
response_generator_);
std::ostringstream uri;
uri << "test:///servername_not_used";
channel_ =
CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args);
stub_ = grpc::testing::EchoTestService::NewStub(channel_);
}
ClientStats WaitForLoadReports() {
ClientStats client_stats;
for (const auto& balancer : balancers_) {
client_stats += balancer->WaitForLoadReport();
}
return client_stats;
}
struct AddressData {
int port;
bool is_balancer;
grpc::string balancer_name;
};
void SetNextResolution(const std::vector<AddressData>& address_data) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_lb_addresses* addresses =
grpc_lb_addresses_create(address_data.size(), nullptr);
for (size_t i = 0; i < address_data.size(); ++i) {
char* lb_uri_str;
gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port);
grpc_uri* lb_uri = grpc_uri_parse(&exec_ctx, lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
grpc_lb_addresses_set_address_from_uri(
addresses, i, lb_uri, address_data[i].is_balancer,
address_data[i].balancer_name.c_str(), nullptr);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
grpc_fake_resolver_response_generator_set_response(
&exec_ctx, response_generator_, &fake_result);
grpc_lb_addresses_destroy(&exec_ctx, addresses);
grpc_exec_ctx_finish(&exec_ctx);
}
const std::vector<int> GetBackendPorts() const {
std::vector<int> backend_ports;
for (const auto& bs : backend_servers_) {
backend_ports.push_back(bs.port_);
}
return backend_ports;
}
void ScheduleResponseForBalancer(size_t i,
const LoadBalanceResponse& response,
int delay_ms) {
balancers_.at(i)->add_response(response, delay_ms);
}
std::vector<std::pair<Status, EchoResponse>> SendRpc(const string& message,
int num_rpcs,
int timeout_ms = 1000) {
std::vector<std::pair<Status, EchoResponse>> results;
EchoRequest request;
EchoResponse response;
request.set_message(message);
for (int i = 0; i < num_rpcs; i++) {
ClientContext context;
context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms));
Status status = stub_->Echo(&context, request, &response);
results.push_back(std::make_pair(status, response));
}
return results;
}
template <typename T>
struct ServerThread {
explicit ServerThread(const grpc::string& type,
const grpc::string& server_host, T* service)
: type_(type), service_(service) {
port_ = grpc_pick_unused_port_or_die();
gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_);
std::mutex mu;
std::condition_variable cond;
thread_.reset(new std::thread(
std::bind(&ServerThread::Start, this, server_host, &mu, &cond)));
std::unique_lock<std::mutex> lock(mu);
cond.wait(lock);
gpr_log(GPR_INFO, "%s server startup complete", type_.c_str());
}
void Start(const grpc::string& server_host, std::mutex* mu,
std::condition_variable* cond) {
std::ostringstream server_address;
server_address << server_host << ":" << port_;
ServerBuilder builder;
builder.AddListeningPort(server_address.str(),
InsecureServerCredentials());
builder.RegisterService(service_);
server_ = builder.BuildAndStart();
std::lock_guard<std::mutex> lock(*mu);
cond->notify_one();
}
void Shutdown() {
gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str());
server_->Shutdown();
thread_->join();
gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str());
}
int port_;
grpc::string type_;
std::unique_ptr<Server> server_;
T* service_;
std::unique_ptr<std::thread> thread_;
};
const grpc::string kMessage_ = "Live long and prosper.";
const grpc::string server_host_;
const size_t num_backends_;
const size_t num_balancers_;
const int client_load_reporting_interval_seconds_;
std::shared_ptr<Channel> channel_;
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
std::vector<std::unique_ptr<BackendServiceImpl>> backends_;
std::vector<std::unique_ptr<BalancerServiceImpl>> balancers_;
std::vector<ServerThread<BackendService>> backend_servers_;
std::vector<ServerThread<BalancerService>> balancer_servers_;
grpc_fake_resolver_response_generator* response_generator_;
};
class SingleBalancerTest : public GrpclbEnd2endTest {
public:
SingleBalancerTest() : GrpclbEnd2endTest(4, 1, 0) {}
};
TEST_F(SingleBalancerTest, Vanilla) {
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()), 0);
// Make sure that trying to connect works without a call.
channel_->GetState(true /* try_to_connect */);
// Start servers and send 100 RPCs per server.
const auto& statuses_and_responses = SendRpc(kMessage_, 100 * num_backends_);
for (const auto& status_and_response : statuses_and_responses) {
EXPECT_TRUE(status_and_response.first.ok());
EXPECT_EQ(status_and_response.second.message(), kMessage_);
}
// Each backend should have gotten 100 requests.
for (size_t i = 0; i < backends_.size(); ++i) {
EXPECT_EQ(100, backend_servers_[i].service_->request_count());
}
// The balancer got a single request.
EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
// and sent a single response.
EXPECT_EQ(1, balancer_servers_[0].service_->response_count());
// Check LB policy name for the channel.
EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
}
TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor();
const int kCallDeadlineMs = 1000 * grpc_test_slowdown_factor();
// First response is an empty serverlist, sent right away.
ScheduleResponseForBalancer(0, LoadBalanceResponse(), 0);
// Send non-empty serverlist only after kServerlistDelayMs
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()),
kServerlistDelayMs);
const auto t0 = system_clock::now();
// Client will block: LB will initially send empty serverlist.
const auto& statuses_and_responses =
SendRpc(kMessage_, num_backends_, kCallDeadlineMs);
const auto ellapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
system_clock::now() - t0);
// but eventually, the LB sends a serverlist update that allows the call to
// proceed. The call delay must be larger than the delay in sending the
// populated serverlist but under the call's deadline.
EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs);
EXPECT_LT(ellapsed_ms.count(), kCallDeadlineMs);
// Each backend should have gotten 1 request.
for (size_t i = 0; i < backends_.size(); ++i) {
EXPECT_EQ(1, backend_servers_[i].service_->request_count());
}
for (const auto& status_and_response : statuses_and_responses) {
EXPECT_TRUE(status_and_response.first.ok());
EXPECT_EQ(status_and_response.second.message(), kMessage_);
}
// The balancer got a single request.
EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
// and sent two responses.
EXPECT_EQ(2, balancer_servers_[0].service_->response_count());
// Check LB policy name for the channel.
EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
}
TEST_F(SingleBalancerTest, RepeatedServerlist) {
constexpr int kServerlistDelayMs = 100;
// Send a serverlist right away.
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()), 0);
// ... and the same one a bit later.
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()),
kServerlistDelayMs);
// Send num_backends/2 requests.
auto statuses_and_responses = SendRpc(kMessage_, num_backends_ / 2);
// only the first half of the backends will receive them.
for (size_t i = 0; i < backends_.size(); ++i) {
if (i < backends_.size() / 2)
EXPECT_EQ(1, backend_servers_[i].service_->request_count());
else
EXPECT_EQ(0, backend_servers_[i].service_->request_count());
}
EXPECT_EQ(statuses_and_responses.size(), num_backends_ / 2);
for (const auto& status_and_response : statuses_and_responses) {
EXPECT_TRUE(status_and_response.first.ok());
EXPECT_EQ(status_and_response.second.message(), kMessage_);
}
// Wait for the (duplicated) serverlist update.
gpr_sleep_until(gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_millis(kServerlistDelayMs * 1.1, GPR_TIMESPAN)));
// Verify the LB has sent two responses.
EXPECT_EQ(2, balancer_servers_[0].service_->response_count());
// Some more calls to complete the total number of backends.
statuses_and_responses = SendRpc(
kMessage_,
num_backends_ / 2 + (num_backends_ & 0x1) /* extra one if num_bes odd */);
// Because a duplicated serverlist should have no effect, all backends must
// have been hit once now.
for (size_t i = 0; i < backends_.size(); ++i) {
EXPECT_EQ(1, backend_servers_[i].service_->request_count());
}
EXPECT_EQ(statuses_and_responses.size(), num_backends_ / 2);
for (const auto& status_and_response : statuses_and_responses) {
EXPECT_TRUE(status_and_response.first.ok());
EXPECT_EQ(status_and_response.second.message(), kMessage_);
}
// The balancer got a single request.
EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
// Check LB policy name for the channel.
EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
}
class SingleBalancerWithClientLoadReportingTest : public GrpclbEnd2endTest {
public:
SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 2) {}
};
TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) {
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts()), 0);
// Start servers and send 100 RPCs per server.
const auto& statuses_and_responses = SendRpc(kMessage_, 100 * num_backends_);
for (const auto& status_and_response : statuses_and_responses) {
EXPECT_TRUE(status_and_response.first.ok());
EXPECT_EQ(status_and_response.second.message(), kMessage_);
}
// Each backend should have gotten 100 requests.
for (size_t i = 0; i < backends_.size(); ++i) {
EXPECT_EQ(100, backend_servers_[i].service_->request_count());
}
// The balancer got a single request.
EXPECT_EQ(1, balancer_servers_[0].service_->request_count());
// and sent a single response.
EXPECT_EQ(1, balancer_servers_[0].service_->response_count());
const ClientStats client_stats = WaitForLoadReports();
EXPECT_EQ(100 * num_backends_, client_stats.num_calls_started);
EXPECT_EQ(100 * num_backends_, client_stats.num_calls_finished);
EXPECT_EQ(0U, client_stats.num_calls_finished_with_drop_for_rate_limiting);
EXPECT_EQ(0U, client_stats.num_calls_finished_with_drop_for_load_balancing);
EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send);
EXPECT_EQ(100 * num_backends_,
client_stats.num_calls_finished_known_received);
}
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc_init();
grpc_test_init(argc, argv);
grpc_fake_resolver_init();
::testing::InitGoogleTest(&argc, argv);
const auto result = RUN_ALL_TESTS();
grpc_shutdown();
return result;
}

@ -118,7 +118,7 @@ void ThreadManagerTest::PerformTest() {
// The number of times DoWork() was called is equal to the number of times // The number of times DoWork() was called is equal to the number of times
// WORK_FOUND was returned // WORK_FOUND was returned
gpr_log(GPR_DEBUG, "DoWork() called %ld times", gpr_log(GPR_DEBUG, "DoWork() called %" PRIdPTR " times",
gpr_atm_no_barrier_load(&num_do_work_)); gpr_atm_no_barrier_load(&num_do_work_));
GPR_ASSERT(gpr_atm_no_barrier_load(&num_do_work_) == GPR_ASSERT(gpr_atm_no_barrier_load(&num_do_work_) ==
gpr_atm_no_barrier_load(&num_work_found_)); gpr_atm_no_barrier_load(&num_work_found_));

@ -91,7 +91,7 @@ void CliCall::Write(const grpc::string& request) {
void* got_tag; void* got_tag;
bool ok; bool ok;
grpc_slice s = grpc_slice_from_copied_string(request.c_str()); gpr_slice s = gpr_slice_from_copied_buffer(request.data(), request.size());
grpc::Slice req_slice(s, grpc::Slice::STEAL_REF); grpc::Slice req_slice(s, grpc::Slice::STEAL_REF);
grpc::ByteBuffer send_buffer(&req_slice, 1); grpc::ByteBuffer send_buffer(&req_slice, 1);
call_->Write(send_buffer, tag(2)); call_->Write(send_buffer, tag(2));

@ -251,4 +251,14 @@
typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
#endif #endif
/* Undefine UNICODE, as c-ares does not use the ANSI version of functions */
/* explicitly. */
#ifdef UNICODE
# undef UNICODE
#endif
#ifdef _UNICODE
# undef _UNICODE
#endif
#endif /* __CARES_BUILD_H */ #endif /* __CARES_BUILD_H */

@ -910,10 +910,14 @@ src/core/ext/filters/client_channel/http_proxy.c \
src/core/ext/filters/client_channel/http_proxy.h \ src/core/ext/filters/client_channel/http_proxy.h \
src/core/ext/filters/client_channel/lb_policy.c \ src/core/ext/filters/client_channel/lb_policy.c \
src/core/ext/filters/client_channel/lb_policy.h \ src/core/ext/filters/client_channel/lb_policy.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \

@ -1,41 +0,0 @@
#!/bin/bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
git submodule update --init
# download fuzzer docker image from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
# runtime 23 * 60 mins
config=asan-trace-cmp runtime=82800 tools/jenkins/run_fuzzer.sh api_fuzzer

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_client.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -1,41 +0,0 @@
#!/bin/bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
git submodule update --init
# download fuzzer docker image from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
# runtime 23 * 60 mins
config=asan-trace-cmp runtime=82800 tools/jenkins/run_fuzzer.sh client_fuzzer

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_hpack_parser.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -1,41 +0,0 @@
#!/bin/bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
git submodule update --init
# download fuzzer docker image from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
config=asan-trace-cmp tools/jenkins/run_fuzzer.sh hpack_parser_fuzzer_test

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_http_request.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -1,41 +0,0 @@
#!/bin/bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
git submodule update --init
# download fuzzer docker image from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
config=asan-trace-cmp tools/jenkins/run_fuzzer.sh http_request_fuzzer_test

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_json.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_nanopb_response.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -1,40 +0,0 @@
#!/bin/bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
git submodule update --init
# download fuzzer docker image from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
config=asan-trace-cmp tools/jenkins/run_fuzzer.sh nanopb_fuzzer_response_test

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_server.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -1,41 +0,0 @@
#!/bin/bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
git submodule update --init
# download fuzzer docker image from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
# runtime 23 * 60 mins
config=asan-trace-cmp runtime=82800 tools/jenkins/run_fuzzer.sh server_fuzzer

@ -1,39 +0,0 @@
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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_fuzzer_uri.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value
action {
define_artifacts {
regex: "git/grpc/fuzzer_output/**"
}
}

@ -41,18 +41,10 @@ clang --version || true
docker --version || true docker --version || true
# Need to increase open files limit for c tests # Need to increase open files limit for c tests
ulimit -n 2000 ulimit -n 32768
git submodule update --init git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests.py -l c -t -x sponge_log.xml || FAILED="true" tools/run_tests/run_tests_matrix.py -f basictests linux --inner_jobs 16 -j 1 --internal_ci
# kill port_server.py to prevent the build from hanging
ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9
if [ "$FAILED" != "" ]
then
exit 1
fi

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f portability linux tools/run_tests/run_tests_matrix.py -f portability linux --inner_jobs 16 -j 1 --internal_ci

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f portability linux --build_only tools/run_tests/run_tests_matrix.py -f portability linux --internal_ci --build_only

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f c asan tools/run_tests/run_tests_matrix.py -f c asan --inner_jobs 16 -j 1 --internal_ci

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f c msan tools/run_tests/run_tests_matrix.py -f c msan --inner_jobs 16 -j 1 --internal_ci

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f c tsan tools/run_tests/run_tests_matrix.py -f c tsan --inner_jobs 16 -j 1 --internal_ci

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f c++ asan tools/run_tests/run_tests_matrix.py -f c++ asan --inner_jobs 16 -j 1 --internal_ci

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f c++ tsan tools/run_tests/run_tests_matrix.py -f c++ tsan --inner_jobs 16 -j 1 --internal_ci

@ -30,10 +30,10 @@
# Config file for the internal CI (in protobuf text format) # Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository. # Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_fuzzer_api.sh" build_file: "grpc/tools/internal_ci/macos/grpc_master.sh"
timeout_mins: 1440 # 24 hours is the maximum allowed value timeout_mins: 240
action { action {
define_artifacts { define_artifacts {
regex: "git/grpc/fuzzer_output/**" regex: "**/*sponge_log.xml"
} }
} }

@ -35,7 +35,12 @@ cd $(dirname $0)/../../..
git submodule update --init git submodule update --init
# download fuzzer docker image from dockerhub tools/run_tests/run_tests_matrix.py -f basictests macos --internal_ci || FAILED="true"
export DOCKERHUB_ORGANIZATION=grpctesting
config=asan-trace-cmp tools/jenkins/run_fuzzer.sh json_fuzzer_test
# kill port_server.py to prevent the build from hanging
ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9
if [ "$FAILED" != "" ]
then
exit 1
fi

@ -36,7 +36,7 @@ cd /d %~dp0\..\..\..
git submodule update --init git submodule update --init
python tools/run_tests/run_tests_matrix.py -f basictests windows -j 1 --inner_jobs 8 || goto :error python tools/run_tests/run_tests_matrix.py -f basictests windows -j 1 --inner_jobs 8 --internal_ci || goto :error
goto :EOF goto :EOF
:error :error

@ -36,7 +36,7 @@ cd /d %~dp0\..\..\..
git submodule update --init git submodule update --init
python tools/run_tests/run_tests_matrix.py -f portability windows -j 1 --inner_jobs 8 || goto :error python tools/run_tests/run_tests_matrix.py -f portability windows -j 1 --inner_jobs 8 --internal_ci || goto :error
goto :EOF goto :EOF
:error :error

@ -33,7 +33,7 @@ the script also supports orchestrating test runs with client and server running
to BigQuery. to BigQuery.
###### Example ###### Example
`tools/run_tests/run_peformance_tests.py -l c++ node` `tools/run_tests/run_performance_tests.py -l c++ node`
###### Useful options ###### Useful options
- `--regex` use regex to select particular scenarios to run. - `--regex` use regex to select particular scenarios to run.

@ -48,7 +48,7 @@ electron_versions=( 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 )
for version in ${node_versions[@]} for version in ${node_versions[@]}
do do
./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH --grpc_alpine=true
cp -r build/stage/* artifacts/ cp -r build/stage/* artifacts/
done done

@ -3275,6 +3275,29 @@
"third_party": false, "third_party": false,
"type": "target" "type": "target"
}, },
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test_util",
"grpc_test_util"
],
"headers": [
"src/proto/grpc/lb/v1/load_balancer.grpc.pb.h",
"src/proto/grpc/lb/v1/load_balancer.pb.h",
"src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
],
"is_filegroup": false,
"language": "c++",
"name": "grpclb_end2end_test",
"src": [
"test/cpp/end2end/grpclb_end2end_test.cc"
],
"third_party": false,
"type": "target"
},
{ {
"deps": [ "deps": [
"gpr", "gpr",
@ -6026,8 +6049,7 @@
"grpc++_codegen_base_src", "grpc++_codegen_base_src",
"grpc++_codegen_proto", "grpc++_codegen_proto",
"grpc++_config_proto", "grpc++_config_proto",
"grpc_test_util", "grpc_test_util"
"thrift_util"
], ],
"headers": [ "headers": [
"src/proto/grpc/health/v1/health.grpc.pb.h", "src/proto/grpc/health/v1/health.grpc.pb.h",
@ -8212,8 +8234,10 @@
"nanopb" "nanopb"
], ],
"headers": [ "headers": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
], ],
@ -8221,10 +8245,14 @@
"language": "c", "language": "c",
"name": "grpc_lb_policy_grpclb", "name": "grpc_lb_policy_grpclb",
"src": [ "src": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
@ -8242,8 +8270,10 @@
"nanopb" "nanopb"
], ],
"headers": [ "headers": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
], ],
@ -8251,10 +8281,14 @@
"language": "c", "language": "c",
"name": "grpc_lb_policy_grpclb_secure", "name": "grpc_lb_policy_grpclb_secure",
"src": [ "src": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
@ -9129,23 +9163,5 @@
], ],
"third_party": false, "third_party": false,
"type": "filegroup" "type": "filegroup"
},
{
"deps": [
"grpc++_codegen_base"
],
"headers": [
"include/grpc++/impl/codegen/thrift_serializer.h",
"include/grpc++/impl/codegen/thrift_utils.h"
],
"is_filegroup": true,
"language": "c++",
"name": "thrift_util",
"src": [
"include/grpc++/impl/codegen/thrift_serializer.h",
"include/grpc++/impl/codegen/thrift_utils.h"
],
"third_party": false,
"type": "filegroup"
} }
] ]

@ -3395,6 +3395,28 @@
"windows" "windows"
] ]
}, },
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "grpclb_end2end_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{ {
"args": [], "args": [],
"ci_platforms": [ "ci_platforms": [

@ -46,6 +46,4 @@ case "$CONFIG" in
*) config_flag='--release' ;; *) config_flag='--release' ;;
esac esac
uv_flag=$2 npm install --unsafe-perm --build-from-source $config_flag
npm install --unsafe-perm --build-from-source $uv_flag $config_flag

@ -37,7 +37,10 @@ mkdir build
cd build cd build
@rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly @rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly
cmake -G "Visual Studio 14 2015" -DgRPC_BUILD_TESTS=ON -DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe" ../.. || goto :error @rem If yasm is not on the path, use hardcoded path instead.
yasm --version || set USE_HARDCODED_YASM_PATH_MAYBE=-DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe"
cmake -G "Visual Studio 14 2015" -DgRPC_BUILD_TESTS=ON %USE_HARDCODED_YASM_PATH_MAYBE% ../.. || goto :error
endlocal endlocal

@ -42,8 +42,12 @@ mkdir build
cd build cd build
mkdir %ARCHITECTURE% mkdir %ARCHITECTURE%
cd %ARCHITECTURE% cd %ARCHITECTURE%
@rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly @rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly
cmake -G "Visual Studio 14 2015" -A %ARCHITECTURE% -DgRPC_BUILD_TESTS=OFF -DgRPC_MSVC_STATIC_RUNTIME=ON -DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe" ../../.. || goto :error @rem If yasm is not on the path, use hardcoded path instead.
yasm --version || set USE_HARDCODED_YASM_PATH_MAYBE=-DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe"
cmake -G "Visual Studio 14 2015" -A %ARCHITECTURE% -DgRPC_BUILD_TESTS=OFF -DgRPC_MSVC_STATIC_RUNTIME=ON %USE_HARDCODED_YASM_PATH_MAYBE% ../../.. || goto :error
cd ..\..\..\src\csharp cd ..\..\..\src\csharp

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save