Merge branch 'master' into chttp2transportcomment

pull/23575/head
Yash Tibrewal 5 years ago
commit 51daf9701a
  1. 1
      BUILD
  2. 1
      BUILD.gn
  3. 19
      CMakeLists.txt
  4. 10
      Makefile
  5. 2
      build_autogenerated.yaml
  6. 13
      config.m4
  7. 13
      config.w32
  8. 1
      doc/python/sphinx/grpc.rst
  9. 1
      gRPC-C++.podspec
  10. 1
      gRPC-Core.podspec
  11. 2
      grpc.def
  12. 37
      grpc.gemspec
  13. 2
      grpc.gyp
  14. 45
      include/grpc/grpc_security.h
  15. 37
      package.xml
  16. 29
      src/core/ext/filters/client_channel/client_channel.cc
  17. 6
      src/core/ext/filters/client_channel/health/health_check_client.cc
  18. 2
      src/core/ext/filters/client_channel/lb_policy.h
  19. 10
      src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc
  20. 28
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  21. 32
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  22. 39
      src/core/ext/filters/client_channel/lb_policy/priority/priority.cc
  23. 9
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  24. 29
      src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
  25. 28
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  26. 30
      src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
  27. 23
      src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc
  28. 20
      src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc
  29. 9
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  30. 66
      src/core/ext/filters/client_channel/subchannel.cc
  31. 11
      src/core/ext/filters/client_channel/subchannel.h
  32. 2
      src/core/ext/filters/client_channel/xds/xds_channel_secure.cc
  33. 8
      src/core/ext/filters/client_channel/xds/xds_client.cc
  34. 3
      src/core/ext/filters/max_age/max_age_filter.cc
  35. 18
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  36. 3
      src/core/ext/transport/inproc/inproc_transport.cc
  37. 94
      src/core/lib/security/credentials/google_default/google_default_credentials.cc
  38. 3
      src/core/lib/surface/server.cc
  39. 31
      src/core/lib/transport/connectivity_state.cc
  40. 24
      src/core/lib/transport/connectivity_state.h
  41. 13
      src/core/lib/transport/error_utils.cc
  42. 6
      src/core/lib/transport/error_utils.h
  43. 3
      src/cpp/client/secure_credentials.cc
  44. 2
      src/php/ext/grpc/channel_credentials.c
  45. 17
      src/python/grpcio/grpc/__init__.py
  46. 19
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
  47. 2
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  48. 10
      src/python/grpcio/grpc_core_dependencies.py
  49. 9
      src/python/grpcio_tests/tests/interop/BUILD.bazel
  50. 39
      src/python/grpcio_tests/tests/interop/client.py
  51. 2
      src/python/grpcio_tests/tests_aio/interop/BUILD.bazel
  52. 2
      src/python/grpcio_tests/tests_aio/interop/client.py
  53. 4
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  54. 8
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  55. 3
      templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template
  56. 117
      test/core/security/credentials_test.cc
  57. 3
      test/core/surface/lame_client_test.cc
  58. 2
      test/core/surface/public_headers_must_be_c89.c
  59. 3
      test/core/transport/chttp2/too_many_pings_test.cc
  60. 81
      test/core/transport/connectivity_state_test.cc
  61. 8
      test/core/util/test_lb_policies.cc
  62. 3
      tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh
  63. 4
      tools/run_tests/run_interop_tests.py

@ -956,6 +956,7 @@ grpc_cc_library(
external_deps = [
"madler_zlib",
"absl/container:inlined_vector",
"absl/status",
"absl/types:optional",
],
language = "c++",

@ -991,6 +991,7 @@ config("grpc_config") {
":upb",
":absl/types:optional",
":absl/strings:strings",
":absl/status:status",
":absl/container:inlined_vector",
"//third_party/cares",
":address_sorting",

@ -111,23 +111,32 @@ set(gRPC_ABSL_USED_TARGETS
absl_civil_time
absl_compressed_tuple
absl_config
absl_cord
absl_core_headers
absl_debugging_internal
absl_demangle_internal
absl_dynamic_annotations
absl_endian
absl_errno_saver
absl_fixed_array
absl_function_ref
absl_inlined_vector
absl_inlined_vector_internal
absl_int128
absl_log_severity
absl_malloc_internal
absl_memory
absl_optional
absl_raw_logging_internal
absl_span
absl_spinlock_wait
absl_stacktrace
absl_status
absl_str_format
absl_str_format_internal
absl_strings
absl_strings_internal
absl_symbolize
absl_throw_delegate
absl_time
absl_time_zone
@ -1793,6 +1802,7 @@ target_link_libraries(grpc
upb
absl::optional
absl::strings
absl::status
absl::inlined_vector
)
if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
@ -2395,6 +2405,7 @@ target_link_libraries(grpc_unsecure
upb
absl::optional
absl::strings
absl::status
absl::inlined_vector
)
if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
@ -15546,7 +15557,7 @@ generate_pkgconfig(
"high performance general RPC framework"
"${gRPC_CORE_VERSION}"
"gpr openssl"
"-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
"-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
""
"grpc.pc")
@ -15556,7 +15567,7 @@ generate_pkgconfig(
"high performance general RPC framework without SSL"
"${gRPC_CORE_VERSION}"
"gpr"
"-lgrpc_unsecure -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
"-lgrpc_unsecure -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
""
"grpc_unsecure.pc")
@ -15566,7 +15577,7 @@ generate_pkgconfig(
"C++ wrapper for gRPC"
"${gRPC_CPP_VERSION}"
"grpc"
"-lgrpc++ -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
"-lgrpc++ -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
""
"grpc++.pc")
@ -15576,6 +15587,6 @@ generate_pkgconfig(
"C++ wrapper for gRPC without SSL"
"${gRPC_CPP_VERSION}"
"grpc_unsecure"
"-lgrpc++_unsecure -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
"-lgrpc++_unsecure -labsl_status -labsl_cord -labsl_symbolize -labsl_demangle_internal -labsl_malloc_internal -labsl_stacktrace -labsl_debugging_internal -labsl_bad_optional_access -labsl_str_format_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_raw_logging_internal -labsl_log_severity -labsl_dynamic_annotations"
""
"grpc++_unsecure.pc")

@ -6236,6 +6236,7 @@ endif
LIBGRPC_ABSEIL_SRC = \
third_party/abseil-cpp/absl/base/dynamic_annotations.cc \
third_party/abseil-cpp/absl/base/internal/cycleclock.cc \
third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc \
third_party/abseil-cpp/absl/base/internal/raw_logging.cc \
third_party/abseil-cpp/absl/base/internal/spinlock.cc \
third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc \
@ -6244,9 +6245,18 @@ LIBGRPC_ABSEIL_SRC = \
third_party/abseil-cpp/absl/base/internal/throw_delegate.cc \
third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc \
third_party/abseil-cpp/absl/base/log_severity.cc \
third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc \
third_party/abseil-cpp/absl/debugging/internal/demangle.cc \
third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc \
third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc \
third_party/abseil-cpp/absl/debugging/stacktrace.cc \
third_party/abseil-cpp/absl/debugging/symbolize.cc \
third_party/abseil-cpp/absl/numeric/int128.cc \
third_party/abseil-cpp/absl/status/status.cc \
third_party/abseil-cpp/absl/status/status_payload_printer.cc \
third_party/abseil-cpp/absl/strings/ascii.cc \
third_party/abseil-cpp/absl/strings/charconv.cc \
third_party/abseil-cpp/absl/strings/cord.cc \
third_party/abseil-cpp/absl/strings/escaping.cc \
third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \
third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \

@ -1163,6 +1163,7 @@ libs:
- upb
- absl/types:optional
- absl/strings:strings
- absl/status:status
- absl/container:inlined_vector
baselib: true
deps_linkage: static
@ -1952,6 +1953,7 @@ libs:
- upb
- absl/types:optional
- absl/strings:strings
- absl/status:status
- absl/container:inlined_vector
baselib: true
deps_linkage: static

@ -509,6 +509,7 @@ if test "$PHP_GRPC" != "no"; then
src/php/ext/grpc/timeval.c \
third_party/abseil-cpp/absl/base/dynamic_annotations.cc \
third_party/abseil-cpp/absl/base/internal/cycleclock.cc \
third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc \
third_party/abseil-cpp/absl/base/internal/raw_logging.cc \
third_party/abseil-cpp/absl/base/internal/spinlock.cc \
third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc \
@ -517,9 +518,18 @@ if test "$PHP_GRPC" != "no"; then
third_party/abseil-cpp/absl/base/internal/throw_delegate.cc \
third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc \
third_party/abseil-cpp/absl/base/log_severity.cc \
third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc \
third_party/abseil-cpp/absl/debugging/internal/demangle.cc \
third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc \
third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc \
third_party/abseil-cpp/absl/debugging/stacktrace.cc \
third_party/abseil-cpp/absl/debugging/symbolize.cc \
third_party/abseil-cpp/absl/numeric/int128.cc \
third_party/abseil-cpp/absl/status/status.cc \
third_party/abseil-cpp/absl/status/status_payload_printer.cc \
third_party/abseil-cpp/absl/strings/ascii.cc \
third_party/abseil-cpp/absl/strings/charconv.cc \
third_party/abseil-cpp/absl/strings/cord.cc \
third_party/abseil-cpp/absl/strings/escaping.cc \
third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \
third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \
@ -971,7 +981,10 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/base)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/base/internal)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/debugging)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/debugging/internal)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/numeric)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/status)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings/internal)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings/internal/str_format)

@ -477,6 +477,7 @@ if (PHP_GRPC != "no") {
"src\\php\\ext\\grpc\\timeval.c " +
"third_party\\abseil-cpp\\absl\\base\\dynamic_annotations.cc " +
"third_party\\abseil-cpp\\absl\\base\\internal\\cycleclock.cc " +
"third_party\\abseil-cpp\\absl\\base\\internal\\low_level_alloc.cc " +
"third_party\\abseil-cpp\\absl\\base\\internal\\raw_logging.cc " +
"third_party\\abseil-cpp\\absl\\base\\internal\\spinlock.cc " +
"third_party\\abseil-cpp\\absl\\base\\internal\\spinlock_wait.cc " +
@ -485,9 +486,18 @@ if (PHP_GRPC != "no") {
"third_party\\abseil-cpp\\absl\\base\\internal\\throw_delegate.cc " +
"third_party\\abseil-cpp\\absl\\base\\internal\\unscaledcycleclock.cc " +
"third_party\\abseil-cpp\\absl\\base\\log_severity.cc " +
"third_party\\abseil-cpp\\absl\\debugging\\internal\\address_is_readable.cc " +
"third_party\\abseil-cpp\\absl\\debugging\\internal\\demangle.cc " +
"third_party\\abseil-cpp\\absl\\debugging\\internal\\elf_mem_image.cc " +
"third_party\\abseil-cpp\\absl\\debugging\\internal\\vdso_support.cc " +
"third_party\\abseil-cpp\\absl\\debugging\\stacktrace.cc " +
"third_party\\abseil-cpp\\absl\\debugging\\symbolize.cc " +
"third_party\\abseil-cpp\\absl\\numeric\\int128.cc " +
"third_party\\abseil-cpp\\absl\\status\\status.cc " +
"third_party\\abseil-cpp\\absl\\status\\status_payload_printer.cc " +
"third_party\\abseil-cpp\\absl\\strings\\ascii.cc " +
"third_party\\abseil-cpp\\absl\\strings\\charconv.cc " +
"third_party\\abseil-cpp\\absl\\strings\\cord.cc " +
"third_party\\abseil-cpp\\absl\\strings\\escaping.cc " +
"third_party\\abseil-cpp\\absl\\strings\\internal\\charconv_bigint.cc " +
"third_party\\abseil-cpp\\absl\\strings\\internal\\charconv_parse.cc " +
@ -1007,7 +1017,10 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\base");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\base\\internal");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\debugging");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\debugging\\internal");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\numeric");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\status");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings\\internal");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings\\internal\\str_format");

@ -41,6 +41,7 @@ Create Client Credentials
.. autofunction:: composite_call_credentials
.. autofunction:: composite_channel_credentials
.. autofunction:: local_channel_credentials(local_connect_type=grpc.LocalConnectionType.LOCAL_TCP)
.. autofunction:: compute_engine_channel_credentials
Create Server

@ -210,6 +210,7 @@ Pod::Spec.new do |s|
abseil_version = '1.20200225.0'
ss.dependency 'abseil/container/inlined_vector', abseil_version
ss.dependency 'abseil/memory/memory', abseil_version
ss.dependency 'abseil/status/status', abseil_version
ss.dependency 'abseil/strings/str_format', abseil_version
ss.dependency 'abseil/strings/strings', abseil_version
ss.dependency 'abseil/time/time', abseil_version

@ -176,6 +176,7 @@ Pod::Spec.new do |s|
abseil_version = '1.20200225.0'
ss.dependency 'abseil/container/inlined_vector', abseil_version
ss.dependency 'abseil/memory/memory', abseil_version
ss.dependency 'abseil/status/status', abseil_version
ss.dependency 'abseil/strings/str_format', abseil_version
ss.dependency 'abseil/strings/strings', abseil_version
ss.dependency 'abseil/time/time', abseil_version

@ -97,12 +97,12 @@ EXPORTS
grpc_ssl_session_cache_create_lru
grpc_ssl_session_cache_destroy
grpc_ssl_session_cache_create_channel_arg
grpc_call_credentials_release
grpc_channel_credentials_release
grpc_google_default_credentials_create
grpc_set_ssl_roots_override_callback
grpc_ssl_credentials_create
grpc_ssl_credentials_create_ex
grpc_call_credentials_release
grpc_composite_channel_credentials_create
grpc_composite_call_credentials_create
grpc_google_compute_engine_credentials_create

@ -969,12 +969,15 @@ Gem::Specification.new do |s|
s.files += %w( third_party/abseil-cpp/absl/base/internal/bits.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/cycleclock.cc )
s.files += %w( third_party/abseil-cpp/absl/base/internal/cycleclock.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/direct_mmap.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/endian.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/errno_saver.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/hide_ptr.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/identity.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/inline_variable.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/invoke.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc )
s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_alloc.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/per_thread_tls.h )
s.files += %w( third_party/abseil-cpp/absl/base/internal/raw_logging.cc )
@ -1007,19 +1010,52 @@ Gem::Specification.new do |s|
s.files += %w( third_party/abseil-cpp/absl/base/policy_checks.h )
s.files += %w( third_party/abseil-cpp/absl/base/port.h )
s.files += %w( third_party/abseil-cpp/absl/base/thread_annotations.h )
s.files += %w( third_party/abseil-cpp/absl/container/fixed_array.h )
s.files += %w( third_party/abseil-cpp/absl/container/inlined_vector.h )
s.files += %w( third_party/abseil-cpp/absl/container/internal/compressed_tuple.h )
s.files += %w( third_party/abseil-cpp/absl/container/internal/inlined_vector.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/demangle.cc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/demangle.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/symbolize.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc )
s.files += %w( third_party/abseil-cpp/absl/debugging/internal/vdso_support.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/stacktrace.cc )
s.files += %w( third_party/abseil-cpp/absl/debugging/stacktrace.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize.cc )
s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize.h )
s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize_elf.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc )
s.files += %w( third_party/abseil-cpp/absl/debugging/symbolize_win32.inc )
s.files += %w( third_party/abseil-cpp/absl/functional/function_ref.h )
s.files += %w( third_party/abseil-cpp/absl/functional/internal/function_ref.h )
s.files += %w( third_party/abseil-cpp/absl/memory/memory.h )
s.files += %w( third_party/abseil-cpp/absl/meta/type_traits.h )
s.files += %w( third_party/abseil-cpp/absl/numeric/int128.cc )
s.files += %w( third_party/abseil-cpp/absl/numeric/int128.h )
s.files += %w( third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc )
s.files += %w( third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc )
s.files += %w( third_party/abseil-cpp/absl/status/status.cc )
s.files += %w( third_party/abseil-cpp/absl/status/status.h )
s.files += %w( third_party/abseil-cpp/absl/status/status_payload_printer.cc )
s.files += %w( third_party/abseil-cpp/absl/status/status_payload_printer.h )
s.files += %w( third_party/abseil-cpp/absl/strings/ascii.cc )
s.files += %w( third_party/abseil-cpp/absl/strings/ascii.h )
s.files += %w( third_party/abseil-cpp/absl/strings/charconv.cc )
s.files += %w( third_party/abseil-cpp/absl/strings/charconv.h )
s.files += %w( third_party/abseil-cpp/absl/strings/cord.cc )
s.files += %w( third_party/abseil-cpp/absl/strings/cord.h )
s.files += %w( third_party/abseil-cpp/absl/strings/escaping.cc )
s.files += %w( third_party/abseil-cpp/absl/strings/escaping.h )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/char_map.h )
@ -1027,6 +1063,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_parse.h )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/cord_internal.h )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/escaping.cc )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/escaping.h )
s.files += %w( third_party/abseil-cpp/absl/strings/internal/memutil.cc )

@ -432,6 +432,7 @@
'upb',
'absl/types:optional',
'absl/strings:strings',
'absl/status:status',
'absl/container:inlined_vector',
],
'sources': [
@ -941,6 +942,7 @@
'upb',
'absl/types:optional',
'absl/strings:strings',
'absl/status:status',
'absl/container:inlined_vector',
],
'sources': [

@ -119,6 +119,18 @@ GRPCAPI void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache);
GRPCAPI grpc_arg
grpc_ssl_session_cache_create_channel_arg(grpc_ssl_session_cache* cache);
/** --- grpc_call_credentials object.
A call credentials object represents a way to authenticate on a particular
call. These credentials can be composed with a channel credentials object
so that they are sent with every call on this channel. */
typedef struct grpc_call_credentials grpc_call_credentials;
/** Releases a call credentials object.
The creator of the credentials object is responsible for its release. */
GRPCAPI void grpc_call_credentials_release(grpc_call_credentials* creds);
/** --- grpc_channel_credentials object. ---
A channel credentials object represents a way to authenticate a client on a
@ -133,8 +145,23 @@ GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials* creds);
/** Creates default credentials to connect to a google gRPC service.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. The security level of the
resulting connection is GRPC_PRIVACY_AND_INTEGRITY. */
GRPCAPI grpc_channel_credentials* grpc_google_default_credentials_create(void);
resulting connection is GRPC_PRIVACY_AND_INTEGRITY.
If specified, the supplied call credentials object will be attached to the
returned channel credentials object. The call_credentials object must remain
valid throughout the lifetime of the returned grpc_channel_credentials
object. It is expected that the call credentials object was generated
according to the Application Default Credentials mechanism and asserts the
identity of the default service account of the machine. Supplying any other
sort of call credential will result in undefined behavior, up to and
including the sudden and unexpected failure of RPCs.
If nullptr is supplied, the returned channel credentials object will use a
call credentials object based on the Application Default Credentials
mechanism.
*/
GRPCAPI grpc_channel_credentials* grpc_google_default_credentials_create(
grpc_call_credentials* call_credentials);
/** Callback for getting the SSL roots override from the application.
In case of success, *pem_roots_certs must be set to a NULL terminated string
@ -272,24 +299,14 @@ GRPCAPI grpc_channel_credentials* grpc_ssl_credentials_create_ex(
const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
const grpc_ssl_verify_peer_options* verify_options, void* reserved);
/** --- grpc_call_credentials object.
A call credentials object represents a way to authenticate on a particular
call. These credentials can be composed with a channel credentials object
so that they are sent with every call on this channel. */
typedef struct grpc_call_credentials grpc_call_credentials;
/** Releases a call credentials object.
The creator of the credentials object is responsible for its release. */
GRPCAPI void grpc_call_credentials_release(grpc_call_credentials* creds);
/** Creates a composite channel credentials object. The security level of
* resulting connection is determined by channel_creds. */
GRPCAPI grpc_channel_credentials* grpc_composite_channel_credentials_create(
grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds,
void* reserved);
/** --- composite credentials. */
/** Creates a composite call credentials object. */
GRPCAPI grpc_call_credentials* grpc_composite_call_credentials_create(
grpc_call_credentials* creds1, grpc_call_credentials* creds2,

@ -971,12 +971,15 @@
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/bits.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/cycleclock.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/cycleclock.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/direct_mmap.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/endian.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/errno_saver.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/hide_ptr.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/identity.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/inline_variable.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/invoke.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/low_level_alloc.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/per_thread_tls.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/internal/raw_logging.cc" role="src" />
@ -1009,19 +1012,52 @@
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/policy_checks.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/port.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/thread_annotations.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/fixed_array.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/inlined_vector.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/compressed_tuple.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/inlined_vector.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/demangle.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/demangle.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/symbolize.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/vdso_support.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/stacktrace.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/stacktrace.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/symbolize.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/symbolize.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/symbolize_elf.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/symbolize_win32.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/functional/function_ref.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/functional/internal/function_ref.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/memory/memory.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/meta/type_traits.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/numeric/int128.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/numeric/int128.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status_payload_printer.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status_payload_printer.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/ascii.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/ascii.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/charconv.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/charconv.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/cord.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/cord.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/escaping.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/escaping.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/char_map.h" role="src" />
@ -1029,6 +1065,7 @@
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/charconv_parse.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/cord_internal.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/escaping.cc" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/escaping.h" role="src" />
<file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/internal/memutil.cc" role="src" />

@ -214,7 +214,8 @@ class ChannelData {
grpc_closure* on_complete,
bool cancel);
void Notify(grpc_connectivity_state state) override;
void Notify(grpc_connectivity_state state,
const absl::Status& /* status */) override;
void Cancel();
@ -260,7 +261,8 @@ class ChannelData {
~ChannelData();
void UpdateStateAndPickerLocked(
grpc_connectivity_state state, const char* reason,
grpc_connectivity_state state, const absl::Status& status,
const char* reason,
std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker);
void UpdateServiceConfigInDataPlaneLocked(
@ -1212,7 +1214,7 @@ void ChannelData::ExternalConnectivityWatcher::
}
void ChannelData::ExternalConnectivityWatcher::Notify(
grpc_connectivity_state state) {
grpc_connectivity_state state, const absl::Status& /* status */) {
bool done = false;
if (!done_.CompareExchangeStrong(&done, true, MemoryOrder::RELAXED,
MemoryOrder::RELAXED)) {
@ -1352,19 +1354,21 @@ class ChannelData::ClientChannelControlHelper
}
void UpdateState(
grpc_connectivity_state state,
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) override {
grpc_error* disconnect_error = chand_->disconnect_error();
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
const char* extra = disconnect_error == GRPC_ERROR_NONE
? ""
: " (ignoring -- channel shutting down)";
gpr_log(GPR_INFO, "chand=%p: update: state=%s picker=%p%s", chand_,
ConnectivityStateName(state), picker.get(), extra);
gpr_log(GPR_INFO, "chand=%p: update: state=%s status=(%s) picker=%p%s",
chand_, ConnectivityStateName(state), status.ToString().c_str(),
picker.get(), extra);
}
// Do update only if not shutting down.
if (disconnect_error == GRPC_ERROR_NONE) {
chand_->UpdateStateAndPickerLocked(state, "helper", std::move(picker));
chand_->UpdateStateAndPickerLocked(state, status, "helper",
std::move(picker));
}
}
@ -1701,7 +1705,8 @@ ChannelData::~ChannelData() {
}
void ChannelData::UpdateStateAndPickerLocked(
grpc_connectivity_state state, const char* reason,
grpc_connectivity_state state, const absl::Status& status,
const char* reason,
std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) {
// Clean the control plane when entering IDLE.
if (picker_ == nullptr) {
@ -1711,7 +1716,7 @@ void ChannelData::UpdateStateAndPickerLocked(
received_first_resolver_result_ = false;
}
// Update connectivity state.
state_tracker_.SetState(state, reason);
state_tracker_.SetState(state, status, reason);
if (channelz_node_ != nullptr) {
channelz_node_->SetConnectivityState(state);
channelz_node_->AddTraceEvent(
@ -1938,8 +1943,8 @@ void ChannelData::StartTransportOpLocked(grpc_transport_op* op) {
static_cast<grpc_connectivity_state>(value) == GRPC_CHANNEL_IDLE) {
if (disconnect_error() == GRPC_ERROR_NONE) {
// Enter IDLE state.
UpdateStateAndPickerLocked(GRPC_CHANNEL_IDLE, "channel entering IDLE",
nullptr);
UpdateStateAndPickerLocked(GRPC_CHANNEL_IDLE, absl::Status(),
"channel entering IDLE", nullptr);
}
GRPC_ERROR_UNREF(op->disconnect_with_error);
} else {
@ -1948,7 +1953,7 @@ void ChannelData::StartTransportOpLocked(grpc_transport_op* op) {
GRPC_ERROR_NONE);
disconnect_error_.Store(op->disconnect_with_error, MemoryOrder::RELEASE);
UpdateStateAndPickerLocked(
GRPC_CHANNEL_SHUTDOWN, "shutdown from API",
GRPC_CHANNEL_SHUTDOWN, absl::Status(), "shutdown from API",
absl::make_unique<LoadBalancingPolicy::TransientFailurePicker>(
GRPC_ERROR_REF(op->disconnect_with_error)));
}

@ -91,7 +91,11 @@ void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state,
gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%s reason=%s", this,
ConnectivityStateName(state), reason);
}
if (watcher_ != nullptr) watcher_->Notify(state);
if (watcher_ != nullptr)
watcher_->Notify(state,
state == GRPC_CHANNEL_TRANSIENT_FAILURE
? absl::Status(absl::StatusCode::kUnavailable, reason)
: absl::Status());
}
void HealthCheckClient::Orphan() {

@ -24,6 +24,7 @@
#include <functional>
#include <iterator>
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "src/core/ext/filters/client_channel/server_address.h"
@ -283,6 +284,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Sets the connectivity state and returns a new picker to be used
/// by the client channel.
virtual void UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker>) = 0;
/// Requests that the resolver re-resolve.

@ -45,7 +45,7 @@ class ChildPolicyHandler::Helper
return parent_->channel_control_helper()->CreateSubchannel(args);
}
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override {
if (parent_->shutting_down_) return;
// If this request is from the pending child policy, ignore it until
@ -55,8 +55,9 @@ class ChildPolicyHandler::Helper
if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) {
gpr_log(GPR_INFO,
"[child_policy_handler %p] helper %p: pending child policy %p "
"reports state=%s",
parent_.get(), this, child_, ConnectivityStateName(state));
"reports state=%s (%s)",
parent_.get(), this, child_, ConnectivityStateName(state),
status.ToString().c_str());
}
if (state == GRPC_CHANNEL_CONNECTING) return;
grpc_pollset_set_del_pollset_set(
@ -67,7 +68,8 @@ class ChildPolicyHandler::Helper
// This request is from an outdated child, so ignore it.
return;
}
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
parent_->channel_control_helper()->UpdateState(state, status,
std::move(picker));
}
void RequestReresolution() override {

@ -304,7 +304,7 @@ class GrpcLb : public LoadBalancingPolicy {
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void AddTraceEvent(TraceSeverity severity,
@ -323,15 +323,16 @@ class GrpcLb : public LoadBalancingPolicy {
~StateWatcher() { parent_.reset(DEBUG_LOCATION, "StateWatcher"); }
private:
void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& status) override {
if (parent_->fallback_at_startup_checks_pending_ &&
new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
// In TRANSIENT_FAILURE. Cancel the fallback timer and go into
// fallback mode immediately.
gpr_log(GPR_INFO,
"[grpclb %p] balancer channel in state TRANSIENT_FAILURE; "
"[grpclb %p] balancer channel in state:TRANSIENT_FAILURE (%s); "
"entering fallback mode",
parent_.get());
parent_.get(), status.ToString().c_str());
parent_->fallback_at_startup_checks_pending_ = false;
grpc_timer_cancel(&parent_->lb_fallback_timer_);
parent_->fallback_mode_ = true;
@ -660,6 +661,7 @@ RefCountedPtr<SubchannelInterface> GrpcLb::Helper::CreateSubchannel(
}
void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (parent_->shutting_down_) return;
// Record whether child policy reports READY.
@ -690,16 +692,22 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
state != GRPC_CHANNEL_READY)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
gpr_log(GPR_INFO,
"[grpclb %p helper %p] state=%s passing child picker %p as-is",
parent_.get(), this, ConnectivityStateName(state), picker.get());
"[grpclb %p helper %p] state=%s (%s) passing "
"child picker %p as-is",
parent_.get(), this, ConnectivityStateName(state),
status.ToString().c_str(), picker.get());
}
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
parent_->channel_control_helper()->UpdateState(state, status,
std::move(picker));
return;
}
// Cases 2 and 3a: wrap picker from the child in our own picker.
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p",
parent_.get(), this, ConnectivityStateName(state), picker.get());
gpr_log(GPR_INFO,
"[grpclb %p helper %p] state=%s (%s) wrapping child "
"picker %p",
parent_.get(), this, ConnectivityStateName(state),
status.ToString().c_str(), picker.get());
}
RefCountedPtr<GrpcLbClientStats> client_stats;
if (parent_->lb_calld_ != nullptr &&
@ -707,7 +715,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
client_stats = parent_->lb_calld_->client_stats()->Ref();
}
parent_->channel_control_helper()->UpdateState(
state,
state, status,
absl::make_unique<Picker>(parent_.get(), parent_->serverlist_,
std::move(picker), std::move(client_stats)));
}

@ -30,6 +30,7 @@
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -200,7 +201,7 @@ void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() {
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
return;
}
@ -318,12 +319,13 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
"selected subchannel failed; switching to pending update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
} else {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, absl::make_unique<QueuePicker>(p->Ref(
DEBUG_LOCATION, "QueuePicker")));
GRPC_CHANNEL_CONNECTING, absl::Status(),
absl::make_unique<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker")));
}
} else {
if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
@ -338,20 +340,22 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->selected_ = nullptr;
p->subchannel_list_.reset();
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, absl::make_unique<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker")));
GRPC_CHANNEL_IDLE, absl::Status(),
absl::make_unique<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker")));
} else {
// This is unlikely but can happen when a subchannel has been asked
// to reconnect by a different channel and this channel has dropped
// some connectivity state notifications.
if (connectivity_state == GRPC_CHANNEL_READY) {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY,
GRPC_CHANNEL_READY, absl::Status(),
absl::make_unique<Picker>(subchannel()->Ref()));
} else { // CONNECTING
p->channel_control_helper()->UpdateState(
connectivity_state, absl::make_unique<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker")));
connectivity_state, absl::Status(),
absl::make_unique<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker")));
}
}
}
@ -394,7 +398,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
"failed to connect to all addresses"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
}
}
@ -406,8 +410,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// Only update connectivity state in case 1.
if (subchannel_list() == p->subchannel_list_.get()) {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, absl::make_unique<QueuePicker>(p->Ref(
DEBUG_LOCATION, "QueuePicker")));
GRPC_CHANNEL_CONNECTING, absl::Status(),
absl::make_unique<QueuePicker>(
p->Ref(DEBUG_LOCATION, "QueuePicker")));
}
break;
}
@ -446,7 +451,8 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
}
p->selected_ = this;
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, absl::make_unique<Picker>(subchannel()->Ref()));
GRPC_CHANNEL_READY, absl::Status(),
absl::make_unique<Picker>(subchannel()->Ref()));
for (size_t i = 0; i < subchannel_list()->num_subchannels(); ++i) {
if (i != Index()) {
subchannel_list()->subchannel(i)->ShutdownLocked();

@ -20,6 +20,7 @@
#include <limits.h>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include <grpc/grpc.h>
@ -33,6 +34,7 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/work_serializer.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -113,6 +115,11 @@ class PriorityLb : public LoadBalancingPolicy {
grpc_connectivity_state connectivity_state() const {
return connectivity_state_;
}
const absl::Status& connectivity_status() const {
return connectivity_status_;
}
bool failover_timer_callback_pending() const {
return failover_timer_callback_pending_;
}
@ -150,6 +157,7 @@ class PriorityLb : public LoadBalancingPolicy {
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void AddTraceEvent(TraceSeverity severity,
@ -164,7 +172,7 @@ class PriorityLb : public LoadBalancingPolicy {
const grpc_channel_args* args);
void OnConnectivityStateUpdateLocked(
grpc_connectivity_state state,
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker);
void StartFailoverTimerLocked();
@ -180,6 +188,7 @@ class PriorityLb : public LoadBalancingPolicy {
OrphanablePtr<LoadBalancingPolicy> child_policy_;
grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_CONNECTING;
absl::Status connectivity_status_;
RefCountedPtr<RefCountedPicker> picker_wrapper_;
// States for delayed removal.
@ -334,6 +343,7 @@ void PriorityLb::HandleChildConnectivityStateChangeLocked(
// If it's still READY or IDLE, we stick with this child, so pass
// the new picker up to our parent.
channel_control_helper()->UpdateState(child->connectivity_state(),
child->connectivity_status(),
child->GetPicker());
} else {
// If it's no longer READY or IDLE, we should stop using it.
@ -380,6 +390,7 @@ void PriorityLb::HandleChildConnectivityStateChangeLocked(
// The current priority has returned a new picker, so pass it up to
// our parent.
channel_control_helper()->UpdateState(child->connectivity_state(),
child->connectivity_status(),
child->GetPicker());
}
@ -409,7 +420,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) {
if (child == nullptr) {
if (report_connecting) {
channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING,
GRPC_CHANNEL_CONNECTING, absl::Status(),
absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker")));
}
child = MakeOrphanable<ChildPriority>(
@ -436,7 +447,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) {
}
if (report_connecting) {
channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING,
GRPC_CHANNEL_CONNECTING, absl::Status(),
absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker")));
}
return;
@ -456,7 +467,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) {
GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ready priority"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
}
@ -476,6 +487,7 @@ void PriorityLb::SelectPriorityLocked(uint32_t priority) {
// Update picker.
auto& child = children_[config_->priorities()[priority]];
channel_control_helper()->UpdateState(child->connectivity_state(),
child->connectivity_status(),
child->GetPicker());
}
@ -584,15 +596,18 @@ void PriorityLb::ChildPriority::ResetBackoffLocked() {
}
void PriorityLb::ChildPriority::OnConnectivityStateUpdateLocked(
grpc_connectivity_state state, std::unique_ptr<SubchannelPicker> picker) {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): state update: %s, picker %p",
"[priority_lb %p] child %s (%p): state update: %s (%s) picker %p",
priority_policy_.get(), name_.c_str(), this,
ConnectivityStateName(state), picker.get());
ConnectivityStateName(state), status.ToString().c_str(),
picker.get());
}
// Store the state and picker.
connectivity_state_ = state;
connectivity_status_ = status;
picker_wrapper_ = MakeRefCounted<RefCountedPicker>(std::move(picker));
// If READY or TRANSIENT_FAILURE, cancel failover timer.
if (state == GRPC_CHANNEL_READY || state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
@ -646,7 +661,10 @@ void PriorityLb::ChildPriority::OnFailoverTimerLocked(grpc_error* error) {
priority_policy_.get(), name_.c_str(), this);
}
failover_timer_callback_pending_ = false;
OnConnectivityStateUpdateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, nullptr);
OnConnectivityStateUpdateLocked(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::Status(absl::StatusCode::kUnavailable, "failover timer fired"),
nullptr);
}
Unref(DEBUG_LOCATION, "ChildPriority+OnFailoverTimerLocked");
GRPC_ERROR_UNREF(error);
@ -725,10 +743,11 @@ PriorityLb::ChildPriority::Helper::CreateSubchannel(
}
void PriorityLb::ChildPriority::Helper::UpdateState(
grpc_connectivity_state state, std::unique_ptr<SubchannelPicker> picker) {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (priority_->priority_policy_->shutting_down_) return;
// Notify the priority.
priority_->OnConnectivityStateUpdateLocked(state, std::move(picker));
priority_->OnConnectivityStateUpdateLocked(state, status, std::move(picker));
}
void PriorityLb::ChildPriority::Helper::AddTraceEvent(

@ -40,6 +40,7 @@
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/static_metadata.h"
namespace grpc_core {
@ -322,11 +323,11 @@ void RoundRobin::RoundRobinSubchannelList::
if (num_ready_ > 0) {
/* 1) READY */
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, absl::make_unique<Picker>(p, this));
GRPC_CHANNEL_READY, absl::Status(), absl::make_unique<Picker>(p, this));
} else if (num_connecting_ > 0) {
/* 2) CONNECTING */
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING,
GRPC_CHANNEL_CONNECTING, absl::Status(),
absl::make_unique<QueuePicker>(p->Ref(DEBUG_LOCATION, "QueuePicker")));
} else if (num_transient_failure_ == num_subchannels()) {
/* 3) TRANSIENT_FAILURE */
@ -335,7 +336,7 @@ void RoundRobin::RoundRobinSubchannelList::
"connections to all backends failing"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
}
}
@ -452,7 +453,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
subchannel_list_ = std::move(latest_pending_subchannel_list_);
} else if (subchannel_list_ == nullptr) {

@ -36,6 +36,7 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/work_serializer.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -146,6 +147,7 @@ class WeightedTargetLb : public LoadBalancingPolicy {
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void AddTraceEvent(TraceSeverity severity,
@ -160,7 +162,7 @@ class WeightedTargetLb : public LoadBalancingPolicy {
const grpc_channel_args* args);
void OnConnectivityStateUpdateLocked(
grpc_connectivity_state state,
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker);
static void OnDelayedRemovalTimer(void* arg, grpc_error* error);
@ -375,6 +377,7 @@ void WeightedTargetLb::UpdateStateLocked() {
this, ConnectivityStateName(connectivity_state));
}
std::unique_ptr<SubchannelPicker> picker;
absl::Status status;
switch (connectivity_state) {
case GRPC_CHANNEL_READY:
picker = absl::make_unique<WeightedPicker>(std::move(picker_list));
@ -385,11 +388,15 @@ void WeightedTargetLb::UpdateStateLocked() {
absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker"));
break;
default:
picker = absl::make_unique<TransientFailurePicker>(
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"weighted_target: all children report state TRANSIENT_FAILURE"));
"weighted_target: all children report state TRANSIENT_FAILURE"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
status = grpc_error_to_absl_status(error);
picker = absl::make_unique<TransientFailurePicker>(error);
}
channel_control_helper()->UpdateState(connectivity_state, std::move(picker));
channel_control_helper()->UpdateState(connectivity_state, status,
std::move(picker));
}
//
@ -508,15 +515,17 @@ void WeightedTargetLb::WeightedChild::ResetBackoffLocked() {
}
void WeightedTargetLb::WeightedChild::OnConnectivityStateUpdateLocked(
grpc_connectivity_state state, std::unique_ptr<SubchannelPicker> picker) {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
// Cache the picker in the WeightedChild.
picker_wrapper_ = MakeRefCounted<ChildPickerWrapper>(std::move(picker));
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_weighted_target_trace)) {
gpr_log(GPR_INFO,
"[weighted_target_lb %p] WeightedChild %p %s: connectivity "
"state update: state=%s picker_wrapper=%p",
"state update: state=%s (%s) picker_wrapper=%p",
weighted_target_policy_.get(), this, name_.c_str(),
ConnectivityStateName(state), picker_wrapper_.get());
ConnectivityStateName(state), status.ToString().c_str(),
picker_wrapper_.get());
}
// If the child reports IDLE, immediately tell it to exit idle.
if (state == GRPC_CHANNEL_IDLE) child_policy_->ExitIdleLocked();
@ -589,9 +598,11 @@ WeightedTargetLb::WeightedChild::Helper::CreateSubchannel(
}
void WeightedTargetLb::WeightedChild::Helper::UpdateState(
grpc_connectivity_state state, std::unique_ptr<SubchannelPicker> picker) {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (weighted_child_->weighted_target_policy_->shutting_down_) return;
weighted_child_->OnConnectivityStateUpdateLocked(state, std::move(picker));
weighted_child_->OnConnectivityStateUpdateLocked(state, status,
std::move(picker));
}
void WeightedTargetLb::WeightedChild::Helper::RequestReresolution() {

@ -29,6 +29,7 @@
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -79,7 +80,7 @@ class CdsLb : public LoadBalancingPolicy {
explicit Helper(RefCountedPtr<CdsLb> parent) : parent_(std::move(parent)) {}
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void AddTraceEvent(TraceSeverity severity,
@ -209,7 +210,7 @@ void CdsLb::ClusterWatcher::OnError(grpc_error* error) {
// we keep running with the data we had previously.
if (parent_->child_policy_ == nullptr) {
parent_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
} else {
GRPC_ERROR_UNREF(error);
@ -221,13 +222,15 @@ void CdsLb::ClusterWatcher::OnResourceDoesNotExist() {
"[cdslb %p] CDS resource for %s does not exist -- reporting "
"TRANSIENT_FAILURE",
parent_.get(), parent_->config_->cluster().c_str());
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("CDS resource \"", parent_->config_->cluster(),
"\" does not exist")
.c_str()),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
parent_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::make_unique<TransientFailurePicker>(
GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("CDS resource \"", parent_->config_->cluster(),
"\" does not exist")
.c_str())));
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
parent_->MaybeDestroyChildPolicyLocked();
}
@ -242,13 +245,16 @@ RefCountedPtr<SubchannelInterface> CdsLb::Helper::CreateSubchannel(
}
void CdsLb::Helper::UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (parent_->shutting_down_ || parent_->child_policy_ == nullptr) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) {
gpr_log(GPR_INFO, "[cdslb %p] state updated by child: %s", this,
ConnectivityStateName(state));
gpr_log(GPR_INFO,
"[cdslb %p] state updated by child: %s message_state: (%s)", this,
ConnectivityStateName(state), status.ToString().c_str());
}
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
parent_->channel_control_helper()->UpdateState(state, status,
std::move(picker));
}
void CdsLb::Helper::RequestReresolution() {

@ -40,6 +40,7 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/work_serializer.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/uri/uri_parser.h"
#define GRPC_EDS_DEFAULT_FALLBACK_TIMEOUT 10000
@ -133,7 +134,7 @@ class EdsLb : public LoadBalancingPolicy {
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
// This is a no-op, because we get the addresses from the xds
// client, which is a watch-based API.
@ -214,6 +215,7 @@ class EdsLb : public LoadBalancingPolicy {
// The latest state and picker returned from the child policy.
grpc_connectivity_state child_state_;
absl::Status child_status_;
RefCountedPtr<ChildPickerWrapper> child_picker_;
};
@ -265,16 +267,21 @@ RefCountedPtr<SubchannelInterface> EdsLb::Helper::CreateSubchannel(
}
void EdsLb::Helper::UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (eds_policy_->shutting_down_ || eds_policy_->child_policy_ == nullptr) {
return;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] child policy updated state=%s picker=%p",
eds_policy_.get(), ConnectivityStateName(state), picker.get());
gpr_log(GPR_INFO,
"[edslb %p] child policy updated state=%s (%s) "
"picker=%p",
eds_policy_.get(), ConnectivityStateName(state),
status.ToString().c_str(), picker.get());
}
// Save the state and picker.
eds_policy_->child_state_ = state;
eds_policy_->child_status_ = status;
eds_policy_->child_picker_ =
MakeRefCounted<ChildPickerWrapper>(std::move(picker));
// Wrap the picker in a DropPicker and pass it up.
@ -339,7 +346,7 @@ class EdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface {
// we keep running with the data we had previously.
if (eds_policy_->child_policy_ == nullptr) {
eds_policy_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
} else {
GRPC_ERROR_UNREF(error);
@ -351,11 +358,12 @@ class EdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface {
GPR_ERROR,
"[edslb %p] EDS resource does not exist -- reporting TRANSIENT_FAILURE",
eds_policy_.get());
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("EDS resource does not exist"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
eds_policy_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::make_unique<TransientFailurePicker>(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"EDS resource does not exist")));
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
eds_policy_->MaybeDestroyChildPolicyLocked();
}
@ -688,7 +696,7 @@ EdsLb::CreateChildPolicyConfigLocked() {
error),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
return nullptr;
}
@ -769,13 +777,13 @@ void EdsLb::MaybeUpdateDropPickerLocked() {
// If we're dropping all calls, report READY, regardless of what (or
// whether) the child has reported.
if (drop_config_ != nullptr && drop_config_->drop_all()) {
channel_control_helper()->UpdateState(GRPC_CHANNEL_READY,
channel_control_helper()->UpdateState(GRPC_CHANNEL_READY, absl::Status(),
absl::make_unique<DropPicker>(this));
return;
}
// Update only if we have a child picker.
if (child_picker_ != nullptr) {
channel_control_helper()->UpdateState(child_state_,
channel_control_helper()->UpdateState(child_state_, child_status_,
absl::make_unique<DropPicker>(this));
}
}

@ -120,7 +120,7 @@ class LrsLb : public LoadBalancingPolicy {
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void AddTraceEvent(TraceSeverity severity,
@ -157,6 +157,7 @@ class LrsLb : public LoadBalancingPolicy {
// Latest state and picker reported by the child policy.
grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE;
absl::Status status_;
RefCountedPtr<RefCountedPicker> picker_;
};
@ -266,10 +267,14 @@ void LrsLb::MaybeUpdatePickerLocked() {
auto lrs_picker =
absl::make_unique<LoadReportingPicker>(picker_, locality_stats_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_lrs_trace)) {
gpr_log(GPR_INFO, "[lrs_lb %p] updating connectivity: state=%s picker=%p",
this, ConnectivityStateName(state_), lrs_picker.get());
gpr_log(
GPR_INFO,
"[lrs_lb %p] updating connectivity: state=%s status=(%s) picker=%p",
this, ConnectivityStateName(state_), status_.ToString().c_str(),
lrs_picker.get());
}
channel_control_helper()->UpdateState(state_, std::move(lrs_picker));
channel_control_helper()->UpdateState(state_, status_,
std::move(lrs_picker));
}
}
@ -325,15 +330,19 @@ RefCountedPtr<SubchannelInterface> LrsLb::Helper::CreateSubchannel(
}
void LrsLb::Helper::UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (lrs_policy_->shutting_down_) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_lrs_trace)) {
gpr_log(GPR_INFO,
"[lrs_lb %p] child connectivity state update: state=%s picker=%p",
lrs_policy_.get(), ConnectivityStateName(state), picker.get());
gpr_log(
GPR_INFO,
"[lrs_lb %p] child connectivity state update: state=%s (%s) picker=%p",
lrs_policy_.get(), ConnectivityStateName(state),
status.ToString().c_str(), picker.get());
}
// Save the state and picker.
lrs_policy_->state_ = state;
lrs_policy_->status_ = status;
lrs_policy_->picker_ = MakeRefCounted<RefCountedPicker>(std::move(picker));
// Wrap the picker and return it to the channel.
lrs_policy_->MaybeUpdatePickerLocked();

@ -42,6 +42,7 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/work_serializer.h"
#include "src/core/lib/transport/error_utils.h"
#define GRPC_XDS_ROUTING_CHILD_RETENTION_INTERVAL_MS (15 * 60 * 1000)
@ -165,6 +166,7 @@ class XdsRoutingLb : public LoadBalancingPolicy {
RefCountedPtr<SubchannelInterface> CreateSubchannel(
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void AddTraceEvent(TraceSeverity severity,
@ -464,6 +466,7 @@ void XdsRoutingLb::UpdateStateLocked() {
ConnectivityStateName(connectivity_state));
}
std::unique_ptr<SubchannelPicker> picker;
absl::Status status;
switch (connectivity_state) {
case GRPC_CHANNEL_READY: {
RoutePicker::RouteTable route_table;
@ -493,12 +496,15 @@ void XdsRoutingLb::UpdateStateLocked() {
absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker"));
break;
default:
picker = absl::make_unique<TransientFailurePicker>(grpc_error_set_int(
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"TRANSIENT_FAILURE from XdsRoutingLb"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
status = grpc_error_to_absl_status(error);
picker = absl::make_unique<TransientFailurePicker>(error);
}
channel_control_helper()->UpdateState(connectivity_state, std::move(picker));
channel_control_helper()->UpdateState(connectivity_state, status,
std::move(picker));
}
//
@ -654,13 +660,15 @@ XdsRoutingLb::XdsRoutingChild::Helper::CreateSubchannel(
}
void XdsRoutingLb::XdsRoutingChild::Helper::UpdateState(
grpc_connectivity_state state, std::unique_ptr<SubchannelPicker> picker) {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_routing_lb_trace)) {
gpr_log(GPR_INFO,
"[xds_routing_lb %p] child %s: received update: state=%s picker=%p",
"[xds_routing_lb %p] child %s: received update: state=%s (%s) "
"picker=%p",
xds_routing_child_->xds_routing_policy_.get(),
xds_routing_child_->name_.c_str(), ConnectivityStateName(state),
picker.get());
status.ToString().c_str(), picker.get());
}
if (xds_routing_child_->xds_routing_policy_->shutting_down_) return;
// Cache the picker in the XdsRoutingChild.

@ -114,10 +114,11 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
return parent_->channel_control_helper()->CreateSubchannel(args);
}
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override {
if (parent_->resolver_ == nullptr) return; // Shutting down.
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
parent_->channel_control_helper()->UpdateState(state, status,
std::move(picker));
}
void RequestReresolution() override {
@ -160,7 +161,7 @@ ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy(
if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this);
}
channel_control_helper()->UpdateState(GRPC_CHANNEL_CONNECTING,
channel_control_helper()->UpdateState(GRPC_CHANNEL_CONNECTING, absl::Status(),
absl::make_unique<QueuePicker>(Ref()));
resolver_->StartLocked();
}
@ -214,7 +215,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
"Resolver transient failure", &error, 1);
helper_->ResolverTransientFailure(GRPC_ERROR_REF(state_error));
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(state_error),
absl::make_unique<TransientFailurePicker>(state_error));
}
GRPC_ERROR_UNREF(error);

@ -26,6 +26,8 @@
#include <algorithm>
#include <cstring>
#include "absl/strings/str_format.h"
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
@ -325,7 +327,8 @@ class Subchannel::ConnectedSubchannelStateWatcher
}
private:
void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& status) override {
Subchannel* c = subchannel_;
MutexLock lock(&c->mu_);
switch (new_state) {
@ -343,7 +346,15 @@ class Subchannel::ConnectedSubchannelStateWatcher
if (c->channelz_node() != nullptr) {
c->channelz_node()->SetChildSocket(nullptr);
}
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE);
// We need to construct our own status if the underlying state was
// shutdown since the accompanying status will be StatusCode::OK
// otherwise.
c->SetConnectivityStateLocked(
GRPC_CHANNEL_TRANSIENT_FAILURE,
new_state == GRPC_CHANNEL_SHUTDOWN
? absl::Status(absl::StatusCode::kUnavailable,
"Subchannel has disconnected.")
: status);
c->backoff_begun_ = false;
c->backoff_.Reset();
}
@ -354,7 +365,7 @@ class Subchannel::ConnectedSubchannelStateWatcher
// a callback for READY, because that was the state we started
// this watch from. And a connected subchannel should never go
// from READY to CONNECTING or IDLE.
c->SetConnectivityStateLocked(new_state);
c->SetConnectivityStateLocked(new_state, status);
}
}
}
@ -368,14 +379,15 @@ class Subchannel::AsyncWatcherNotifierLocked {
public:
AsyncWatcherNotifierLocked(
RefCountedPtr<Subchannel::ConnectivityStateWatcherInterface> watcher,
Subchannel* subchannel, grpc_connectivity_state state)
Subchannel* subchannel, grpc_connectivity_state state,
const absl::Status& status)
: watcher_(std::move(watcher)) {
RefCountedPtr<ConnectedSubchannel> connected_subchannel;
if (state == GRPC_CHANNEL_READY) {
connected_subchannel = subchannel->connected_subchannel_;
}
watcher_->PushConnectivityStateChange(
{state, std::move(connected_subchannel)});
{state, status, std::move(connected_subchannel)});
ExecCtx::Run(
DEBUG_LOCATION,
GRPC_CLOSURE_INIT(&closure_,
@ -409,9 +421,10 @@ void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked(
}
void Subchannel::ConnectivityStateWatcherList::NotifyLocked(
Subchannel* subchannel, grpc_connectivity_state state) {
Subchannel* subchannel, grpc_connectivity_state state,
const absl::Status& status) {
for (const auto& p : watchers_) {
new AsyncWatcherNotifierLocked(p.second, subchannel, state);
new AsyncWatcherNotifierLocked(p.second, subchannel, state, status);
}
}
@ -450,7 +463,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher
grpc_connectivity_state initial_state,
RefCountedPtr<Subchannel::ConnectivityStateWatcherInterface> watcher) {
if (state_ != initial_state) {
new AsyncWatcherNotifierLocked(watcher, subchannel_, state_);
new AsyncWatcherNotifierLocked(watcher, subchannel_, state_, status_);
}
watcher_list_.AddWatcherLocked(std::move(watcher));
}
@ -462,7 +475,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher
bool HasWatchers() const { return !watcher_list_.empty(); }
void NotifyLocked(grpc_connectivity_state state) {
void NotifyLocked(grpc_connectivity_state state, const absl::Status& status) {
if (state == GRPC_CHANNEL_READY) {
// If we had not already notified for CONNECTING state, do so now.
// (We may have missed this earlier, because if the transition
@ -470,13 +483,15 @@ class Subchannel::HealthWatcherMap::HealthWatcher
// subchannel may not have sent us a notification for CONNECTING.)
if (state_ != GRPC_CHANNEL_CONNECTING) {
state_ = GRPC_CHANNEL_CONNECTING;
watcher_list_.NotifyLocked(subchannel_, state_);
status_ = status;
watcher_list_.NotifyLocked(subchannel_, state_, status);
}
// If we've become connected, start health checking.
StartHealthCheckingLocked();
} else {
state_ = state;
watcher_list_.NotifyLocked(subchannel_, state_);
status_ = status;
watcher_list_.NotifyLocked(subchannel_, state_, status);
// We're not connected, so stop health checking.
health_check_client_.reset();
}
@ -489,11 +504,13 @@ class Subchannel::HealthWatcherMap::HealthWatcher
}
private:
void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& status) override {
MutexLock lock(&subchannel_->mu_);
if (new_state != GRPC_CHANNEL_SHUTDOWN && health_check_client_ != nullptr) {
state_ = new_state;
watcher_list_.NotifyLocked(subchannel_, new_state);
status_ = status;
watcher_list_.NotifyLocked(subchannel_, new_state, status);
}
}
@ -508,6 +525,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher
grpc_core::UniquePtr<char> health_check_service_name_;
OrphanablePtr<HealthCheckClient> health_check_client_;
grpc_connectivity_state state_;
absl::Status status_;
ConnectivityStateWatcherList watcher_list_;
};
@ -547,9 +565,10 @@ void Subchannel::HealthWatcherMap::RemoveWatcherLocked(
if (!it->second->HasWatchers()) map_.erase(it);
}
void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state) {
void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state,
const absl::Status& status) {
for (const auto& p : map_) {
p.second->NotifyLocked(state);
p.second->NotifyLocked(state, status);
}
}
@ -826,7 +845,7 @@ void Subchannel::WatchConnectivityState(
}
if (health_check_service_name == nullptr) {
if (state_ != initial_state) {
new AsyncWatcherNotifierLocked(watcher, this, state_);
new AsyncWatcherNotifierLocked(watcher, this, state_, status_);
}
watcher_list_.AddWatcherLocked(std::move(watcher));
} else {
@ -928,8 +947,10 @@ const char* SubchannelConnectivityStateChangeString(
} // namespace
// Note: Must be called with a state that is different from the current state.
void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) {
void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
const absl::Status& status) {
state_ = state;
status_ = status;
if (channelz_node_ != nullptr) {
channelz_node_->UpdateConnectivityState(state);
channelz_node_->AddTraceEvent(
@ -938,9 +959,9 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) {
SubchannelConnectivityStateChangeString(state)));
}
// Notify non-health watchers.
watcher_list_.NotifyLocked(this, state);
watcher_list_.NotifyLocked(this, state, status);
// Notify health watchers.
health_watcher_map_.NotifyLocked(state);
health_watcher_map_.NotifyLocked(state, status);
}
void Subchannel::MaybeStartConnectingLocked() {
@ -1012,7 +1033,7 @@ void Subchannel::ContinueConnectingLocked() {
next_attempt_deadline_ = backoff_.NextAttemptTime();
args.deadline = std::max(next_attempt_deadline_, min_deadline);
args.channel_args = args_;
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING);
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, absl::Status());
connector_->Connect(args, &connecting_result_, &on_connecting_finished_);
}
@ -1031,7 +1052,8 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) {
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
} else {
gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error));
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE);
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE,
grpc_error_to_absl_status(error));
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
}
}
@ -1091,7 +1113,7 @@ bool Subchannel::PublishTransportLocked() {
connected_subchannel_->StartWatch(
pollset_set_, MakeOrphanable<ConnectedSubchannelStateWatcher>(this));
// Report initial state.
SetConnectivityStateLocked(GRPC_CHANNEL_READY);
SetConnectivityStateLocked(GRPC_CHANNEL_READY, absl::Status());
return true;
}

@ -182,6 +182,7 @@ class Subchannel {
public:
struct ConnectivityStateChange {
grpc_connectivity_state state;
absl::Status status;
RefCountedPtr<ConnectedSubchannel> connected_subchannel;
};
@ -306,7 +307,8 @@ class Subchannel {
void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher);
// Notifies all watchers in the list about a change to state.
void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state);
void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state,
const absl::Status& status);
void Clear() { watchers_.clear(); }
@ -339,7 +341,8 @@ class Subchannel {
ConnectivityStateWatcherInterface* watcher);
// Notifies the watcher when the subchannel's state changes.
void NotifyLocked(grpc_connectivity_state state);
void NotifyLocked(grpc_connectivity_state state,
const absl::Status& status);
grpc_connectivity_state CheckConnectivityStateLocked(
Subchannel* subchannel, const char* health_check_service_name);
@ -357,7 +360,8 @@ class Subchannel {
class AsyncWatcherNotifierLocked;
// Sets the subchannel's connectivity state to \a state.
void SetConnectivityStateLocked(grpc_connectivity_state state);
void SetConnectivityStateLocked(grpc_connectivity_state state,
const absl::Status& status);
// Methods for connection.
void MaybeStartConnectingLocked();
@ -400,6 +404,7 @@ class Subchannel {
// Connectivity state tracking.
grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE;
absl::Status status_;
// The list of watchers without a health check service name.
ConnectivityStateWatcherList watcher_list_;
// The map of watchers with health check service names.

@ -73,7 +73,7 @@ grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap,
if (!bootstrap.server().channel_creds.empty()) {
for (size_t i = 0; i < bootstrap.server().channel_creds.size(); ++i) {
if (bootstrap.server().channel_creds[i].type == "google_default") {
creds = grpc_google_default_credentials_create();
creds = grpc_google_default_credentials_create(nullptr);
break;
} else if (bootstrap.server().channel_creds[i].type == "fake") {
creds = grpc_fake_transport_security_credentials_create();

@ -398,13 +398,15 @@ class XdsClient::ChannelState::StateWatcher
parent_(std::move(parent)) {}
private:
void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& status) override {
if (!parent_->shutting_down_ &&
new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
// In TRANSIENT_FAILURE. Notify all watchers of error.
gpr_log(GPR_INFO,
"[xds_client %p] xds channel in state TRANSIENT_FAILURE",
parent_->xds_client());
"[xds_client %p] xds channel in state:TRANSIENT_FAILURE "
"status_message:(%s)",
parent_->xds_client(), status.ToString().c_str());
parent_->xds_client()->NotifyOnError(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"xds channel in TRANSIENT_FAILURE"));
}

@ -229,7 +229,8 @@ class ConnectivityWatcher : public AsyncConnectivityStateWatcherInterface {
}
private:
void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& /* status */) override {
if (new_state != GRPC_CHANNEL_SHUTDOWN) return;
{
MutexLock lock(&chand_->max_age_timer_mu);

@ -18,6 +18,8 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "absl/strings/str_format.h"
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -29,7 +31,6 @@
#include <stdio.h>
#include <string.h>
#include "absl/strings/str_format.h"
#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/ext/transport/chttp2/transport/frame_data.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
@ -125,6 +126,7 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t);
static void connectivity_state_set(grpc_chttp2_transport* t,
grpc_connectivity_state state,
const absl::Status& status,
const char* reason);
static void benign_reclaimer(void* t, grpc_error* error);
@ -560,7 +562,8 @@ static void close_transport_locked(grpc_chttp2_transport* t,
}
GPR_ASSERT(error != GRPC_ERROR_NONE);
t->closed_with_error = GRPC_ERROR_REF(error);
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, "close_transport");
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, absl::Status(),
"close_transport");
if (t->ping_state.is_delayed_ping_timer_set) {
grpc_timer_cancel(&t->ping_state.delayed_ping_timer);
}
@ -1103,9 +1106,11 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t,
: static_cast<grpc_millis>(current_keepalive_time_ms *
KEEPALIVE_TIME_BACKOFF_MULTIPLIER);
}
absl::Status status = grpc_error_to_absl_status(t->goaway_error);
// lie: use transient failure from the transport to indicate goaway has been
// received
connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway");
// received.
connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, status,
"got_goaway");
}
static void maybe_start_some_streams(grpc_chttp2_transport* t) {
@ -1140,6 +1145,8 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) {
if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) {
connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::Status(absl::StatusCode::kUnavailable,
"Transport Stream IDs exhausted"),
"no_more_stream_ids");
}
@ -2915,10 +2922,11 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) {
static void connectivity_state_set(grpc_chttp2_transport* t,
grpc_connectivity_state state,
const absl::Status& status,
const char* reason) {
GRPC_CHTTP2_IF_TRACING(
gpr_log(GPR_INFO, "transport %p set connectivity_state=%d", t, state));
t->state_tracker.SetState(state, reason);
t->state_tracker.SetState(state, status, reason);
}
//

@ -1132,7 +1132,8 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
void close_transport_locked(inproc_transport* t) {
INPROC_LOG(GPR_INFO, "close_transport %p %d", t, t->is_closed);
t->state_tracker.SetState(GRPC_CHANNEL_SHUTDOWN, "close transport");
t->state_tracker.SetState(GRPC_CHANNEL_SHUTDOWN, absl::Status(),
"close transport");
if (!t->is_closed) {
t->is_closed = true;
/* Also end all streams on this transport */

@ -49,6 +49,8 @@ using grpc_core::Json;
/* -- Constants. -- */
#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal."
#define GRPC_GOOGLE_CREDENTIAL_CREATION_ERROR \
"Failed to create Google credentials"
/* -- Default credentials. -- */
@ -57,7 +59,6 @@ using grpc_core::Json;
* means the detection is done via network test that is unreliable and the
* unreliable result should not be referred by successive calls. */
static int g_metadata_server_available = 0;
static int g_is_on_gce = 0;
static gpr_mu g_state_mu;
/* Protect a metadata_server_detector instance that can be modified by more than
* one gRPC threads */
@ -89,7 +90,7 @@ grpc_google_default_channel_credentials::create_security_connector(
bool use_alts =
is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer;
/* Return failure if ALTS is selected but not running on GCE. */
if (use_alts && !g_is_on_gce) {
if (use_alts && alts_creds_ == nullptr) {
gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.");
return nullptr;
}
@ -273,59 +274,78 @@ end:
return error;
}
grpc_channel_credentials* grpc_google_default_credentials_create() {
grpc_channel_credentials* result = nullptr;
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds;
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to create Google credentials");
grpc_error* err;
grpc_core::ExecCtx exec_ctx;
static void update_tenancy() {
gpr_once_init(&g_once, init_default_credentials);
grpc_core::MutexLock lock(&g_state_mu);
GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
/* Try a platform-provided hint for GCE. */
if (!g_metadata_server_available) {
g_metadata_server_available = g_gce_tenancy_checker();
}
/* TODO: Add a platform-provided hint for GAE. */
gpr_once_init(&g_once, init_default_credentials);
/* Do a network test for metadata server. */
if (!g_metadata_server_available) {
g_metadata_server_available = is_metadata_server_reachable();
}
}
static bool metadata_server_available() {
grpc_core::MutexLock lock(&g_state_mu);
return static_cast<bool>(g_metadata_server_available);
}
static grpc_core::RefCountedPtr<grpc_call_credentials> make_default_call_creds(
grpc_error** error) {
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds;
grpc_error* err;
/* First, try the environment variable. */
char* path_from_env = gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR);
if (path_from_env != nullptr) {
err = create_default_creds_from_path(path_from_env, &call_creds);
gpr_free(path_from_env);
if (err == GRPC_ERROR_NONE) goto end;
error = grpc_error_add_child(error, err);
if (err == GRPC_ERROR_NONE) return call_creds;
*error = grpc_error_add_child(*error, err);
}
/* Then the well-known file. */
err = create_default_creds_from_path(
grpc_get_well_known_google_credentials_file_path(), &call_creds);
if (err == GRPC_ERROR_NONE) goto end;
error = grpc_error_add_child(error, err);
if (err == GRPC_ERROR_NONE) return call_creds;
*error = grpc_error_add_child(*error, err);
gpr_mu_lock(&g_state_mu);
update_tenancy();
/* Try a platform-provided hint for GCE. */
if (!g_metadata_server_available) {
g_is_on_gce = g_gce_tenancy_checker();
g_metadata_server_available = g_is_on_gce;
}
/* TODO: Add a platform-provided hint for GAE. */
/* Do a network test for metadata server. */
if (!g_metadata_server_available) {
g_metadata_server_available = is_metadata_server_reachable();
}
gpr_mu_unlock(&g_state_mu);
if (g_metadata_server_available) {
if (metadata_server_available()) {
call_creds = grpc_core::RefCountedPtr<grpc_call_credentials>(
grpc_google_compute_engine_credentials_create(nullptr));
if (call_creds == nullptr) {
error = grpc_error_add_child(
error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to get credentials from network"));
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
GRPC_GOOGLE_CREDENTIAL_CREATION_ERROR);
*error = grpc_error_add_child(
*error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to get credentials from network"));
}
}
end:
return call_creds;
}
grpc_channel_credentials* grpc_google_default_credentials_create(
grpc_call_credentials* call_credentials) {
grpc_channel_credentials* result = nullptr;
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds(call_credentials);
grpc_error* error = nullptr;
grpc_core::ExecCtx exec_ctx;
GRPC_API_TRACE("grpc_google_default_credentials_create(%p)", 1,
(call_credentials));
if (call_creds == nullptr) {
call_creds = make_default_call_creds(&error);
}
if (call_creds != nullptr) {
/* Create google default credentials. */
grpc_channel_credentials* ssl_creds =
@ -338,10 +358,8 @@ end:
grpc_alts_credentials_options_destroy(options);
auto creds =
grpc_core::MakeRefCounted<grpc_google_default_channel_credentials>(
alts_creds != nullptr ? alts_creds->Ref() : nullptr,
ssl_creds != nullptr ? ssl_creds->Ref() : nullptr);
if (ssl_creds) ssl_creds->Unref();
if (alts_creds) alts_creds->Unref();
grpc_core::RefCountedPtr<grpc_channel_credentials>(alts_creds),
grpc_core::RefCountedPtr<grpc_channel_credentials>(ssl_creds));
result = grpc_composite_channel_credentials_create(
creds.get(), call_creds.get(), nullptr);
GPR_ASSERT(result != nullptr);

@ -1271,7 +1271,8 @@ class ConnectivityWatcher : public AsyncConnectivityStateWatcherInterface {
}
private:
void OnConnectivityStateChange(grpc_connectivity_state new_state) override {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& /* status */) override {
// Don't do anything until we are being shut down.
if (new_state != GRPC_CHANNEL_SHUTDOWN) return;
// Shut down channel.

@ -58,9 +58,9 @@ const char* ConnectivityStateName(grpc_connectivity_state state) {
class AsyncConnectivityStateWatcherInterface::Notifier {
public:
Notifier(RefCountedPtr<AsyncConnectivityStateWatcherInterface> watcher,
grpc_connectivity_state state,
grpc_connectivity_state state, const absl::Status& status,
const std::shared_ptr<WorkSerializer>& work_serializer)
: watcher_(std::move(watcher)), state_(state) {
: watcher_(std::move(watcher)), state_(state), status_(status) {
if (work_serializer != nullptr) {
work_serializer->Run(
[this]() { SendNotification(this, GRPC_ERROR_NONE); },
@ -76,21 +76,24 @@ class AsyncConnectivityStateWatcherInterface::Notifier {
static void SendNotification(void* arg, grpc_error* /*ignored*/) {
Notifier* self = static_cast<Notifier*>(arg);
if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) {
gpr_log(GPR_INFO, "watcher %p: delivering async notification for %s",
self->watcher_.get(), ConnectivityStateName(self->state_));
gpr_log(GPR_INFO, "watcher %p: delivering async notification for %s (%s)",
self->watcher_.get(), ConnectivityStateName(self->state_),
self->status_.ToString().c_str());
}
self->watcher_->OnConnectivityStateChange(self->state_);
self->watcher_->OnConnectivityStateChange(self->state_, self->status_);
delete self;
}
RefCountedPtr<AsyncConnectivityStateWatcherInterface> watcher_;
const grpc_connectivity_state state_;
const absl::Status status_;
grpc_closure closure_;
};
void AsyncConnectivityStateWatcherInterface::Notify(
grpc_connectivity_state state) {
new Notifier(Ref(), state, work_serializer_); // Deletes itself when done.
grpc_connectivity_state state, const absl::Status& status) {
new Notifier(Ref(), state, status,
work_serializer_); // Deletes itself when done.
}
//
@ -107,7 +110,7 @@ ConnectivityStateTracker::~ConnectivityStateTracker() {
name_, this, p.first, ConnectivityStateName(current_state),
ConnectivityStateName(GRPC_CHANNEL_SHUTDOWN));
}
p.second->Notify(GRPC_CHANNEL_SHUTDOWN);
p.second->Notify(GRPC_CHANNEL_SHUTDOWN, absl::Status());
}
}
@ -126,7 +129,7 @@ void ConnectivityStateTracker::AddWatcher(
name_, this, watcher.get(), ConnectivityStateName(initial_state),
ConnectivityStateName(current_state));
}
watcher->Notify(current_state);
watcher->Notify(current_state, status_);
}
// If we're in state SHUTDOWN, don't add the watcher, so that it will
// be orphaned immediately.
@ -145,15 +148,17 @@ void ConnectivityStateTracker::RemoveWatcher(
}
void ConnectivityStateTracker::SetState(grpc_connectivity_state state,
const absl::Status& status,
const char* reason) {
grpc_connectivity_state current_state = state_.Load(MemoryOrder::RELAXED);
if (state == current_state) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) {
gpr_log(GPR_INFO, "ConnectivityStateTracker %s[%p]: %s -> %s (%s)", name_,
this, ConnectivityStateName(current_state),
ConnectivityStateName(state), reason);
gpr_log(GPR_INFO, "ConnectivityStateTracker %s[%p]: %s -> %s (%s, %s)",
name_, this, ConnectivityStateName(current_state),
ConnectivityStateName(state), reason, status.ToString().c_str());
}
state_.Store(state, MemoryOrder::RELAXED);
status_ = status;
for (const auto& p : watchers_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) {
gpr_log(GPR_INFO,
@ -161,7 +166,7 @@ void ConnectivityStateTracker::SetState(grpc_connectivity_state state,
name_, this, p.first, ConnectivityStateName(current_state),
ConnectivityStateName(state));
}
p.second->Notify(state);
p.second->Notify(state, status);
}
// If the new state is SHUTDOWN, orphan all of the watchers. This
// avoids the need for the callers to explicitly cancel them.

@ -21,6 +21,8 @@
#include <grpc/support/port_platform.h>
#include "absl/status/status.h"
#include <grpc/grpc.h>
#include "src/core/lib/debug/trace.h"
@ -49,7 +51,8 @@ class ConnectivityStateWatcherInterface
virtual ~ConnectivityStateWatcherInterface() = default;
// Notifies the watcher that the state has changed to new_state.
virtual void Notify(grpc_connectivity_state new_state) = 0;
virtual void Notify(grpc_connectivity_state new_state,
const absl::Status& status) = 0;
void Orphan() override { Unref(); }
};
@ -64,7 +67,8 @@ class AsyncConnectivityStateWatcherInterface
// Schedules a closure on the ExecCtx to invoke
// OnConnectivityStateChange() asynchronously.
void Notify(grpc_connectivity_state new_state) override final;
void Notify(grpc_connectivity_state new_state,
const absl::Status& status) override final;
protected:
class Notifier;
@ -76,7 +80,8 @@ class AsyncConnectivityStateWatcherInterface
: work_serializer_(std::move(work_serializer)) {}
// Invoked asynchronously when Notify() is called.
virtual void OnConnectivityStateChange(grpc_connectivity_state new_state) = 0;
virtual void OnConnectivityStateChange(grpc_connectivity_state new_state,
const absl::Status& status) = 0;
private:
std::shared_ptr<WorkSerializer> work_serializer_;
@ -91,8 +96,9 @@ class AsyncConnectivityStateWatcherInterface
class ConnectivityStateTracker {
public:
ConnectivityStateTracker(const char* name,
grpc_connectivity_state state = GRPC_CHANNEL_IDLE)
: name_(name), state_(state) {}
grpc_connectivity_state state = GRPC_CHANNEL_IDLE,
const absl::Status& status = absl::Status())
: name_(name), state_(state), status_(status) {}
~ConnectivityStateTracker();
@ -110,15 +116,21 @@ class ConnectivityStateTracker {
// Sets connectivity state.
// Not thread safe; access must be serialized with an external lock.
void SetState(grpc_connectivity_state state, const char* reason);
void SetState(grpc_connectivity_state state, const absl::Status& status,
const char* reason);
// Gets the current state.
// Thread safe; no need to use an external lock.
grpc_connectivity_state state() const;
// Get the current status.
// Not thread safe; access must be serialized with an external lock.
absl::Status status() const { return status_; }
private:
const char* name_;
Atomic<grpc_connectivity_state> state_;
absl::Status status_;
// TODO(roth): Once we can use C++-14 heterogeneous lookups, this can
// be a set instead of a map.
std::map<ConnectivityStateWatcherInterface*,

@ -123,6 +123,19 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
}
}
absl::Status grpc_error_to_absl_status(grpc_error* error) {
grpc_status_code status;
// TODO(yashykt): This should be updated once we decide on how to use the
// absl::Status payload to capture all the contents of grpc_error.
grpc_slice message;
grpc_error_get_status(error, GRPC_MILLIS_INF_FUTURE, &status, &message,
nullptr /* http_error */, nullptr /* error_string */);
return absl::Status(static_cast<absl::StatusCode>(status),
absl::string_view(reinterpret_cast<const char*>(
GRPC_SLICE_START_PTR(message)),
GRPC_SLICE_LENGTH(message)));
}
bool grpc_error_has_clear_grpc_status(grpc_error* error) {
intptr_t unused;
if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &unused)) {

@ -21,6 +21,8 @@
#include <grpc/support/port_platform.h>
#include "absl/status/status.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/http2_errors.h"
@ -37,6 +39,10 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
grpc_http2_error_code* http_status,
const char** error_string);
/// Utility Function to convert a grpc_error * \a error to an absl::Status.
/// Does NOT consume a ref to grpc_error.
absl::Status grpc_error_to_absl_status(grpc_error* error);
/// A utility function to check whether there is a clear status code that
/// doesn't need to be guessed in \a error. This means that \a error or some
/// child has GRPC_ERROR_INT_GRPC_STATUS set, or that it is GRPC_ERROR_NONE or

@ -97,7 +97,8 @@ std::shared_ptr<CallCredentials> WrapCallCredentials(
std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
grpc::GrpcLibraryCodegen init; // To call grpc_init().
return WrapChannelCredentials(grpc_google_default_credentials_create());
return WrapChannelCredentials(
grpc_google_default_credentials_create(nullptr));
}
// Builds SSL Credentials given SSL specific options

@ -131,7 +131,7 @@ PHP_METHOD(ChannelCredentials, invalidateDefaultRootsPem) {
* @return ChannelCredentials The new default channel credentials object
*/
PHP_METHOD(ChannelCredentials, createDefault) {
grpc_channel_credentials *creds = grpc_google_default_credentials_create();
grpc_channel_credentials *creds = grpc_google_default_credentials_create(NULL);
zval *creds_object = grpc_php_wrap_channel_credentials(creds, NULL, false
TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);

@ -1868,6 +1868,23 @@ def alts_server_credentials():
return ServerCredentials(_cygrpc.server_credentials_alts())
def compute_engine_channel_credentials(call_credentials):
"""Creates a compute engine channel credential.
This credential can only be used in a GCP environment as it relies on
a handshaker service. For more info about ALTS, see
https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security
This channel credential is expected to be used as part of a composite
credential in conjunction with a call credentials that authenticates the
VM's default service account. If used with any other sort of call
credential, the connection may suddenly and unexpectedly begin failing RPCs.
"""
return ChannelCredentials(
_cygrpc.channel_credentials_compute_engine(
call_credentials._credentials))
def channel_ready_future(channel):
"""Creates a Future that tracks when a Channel is ready.

@ -380,3 +380,22 @@ def server_credentials_alts():
# Options can be destroyed as deep copy was performed.
grpc_alts_credentials_options_destroy(c_options)
return credentials
cdef class ComputeEngineChannelCredentials(ChannelCredentials):
cdef grpc_channel_credentials* _c_creds
cdef grpc_call_credentials* _call_creds
def __cinit__(self, CallCredentials call_creds):
self._c_creds = NULL
self._call_creds = call_creds.c()
if self._call_creds == NULL:
raise ValueError("Call credentials may not be NULL.")
cdef grpc_channel_credentials *c(self) except *:
self._c_creds = grpc_google_default_credentials_create(self._call_creds)
return self._c_creds
def channel_credentials_compute_engine(call_creds):
return ComputeEngineChannelCredentials(call_creds)

@ -504,7 +504,7 @@ cdef extern from "grpc/grpc_security.h":
void grpc_set_ssl_roots_override_callback(
grpc_ssl_roots_override_callback cb) nogil
grpc_channel_credentials *grpc_google_default_credentials_create() nogil
grpc_channel_credentials *grpc_google_default_credentials_create(grpc_call_credentials* call_credentials) nogil
grpc_channel_credentials *grpc_ssl_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
verify_peer_options *verify_options, void *reserved) nogil

@ -476,6 +476,7 @@ CORE_SOURCE_FILES = [
'src/core/tsi/transport_security_grpc.cc',
'third_party/abseil-cpp/absl/base/dynamic_annotations.cc',
'third_party/abseil-cpp/absl/base/internal/cycleclock.cc',
'third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc',
'third_party/abseil-cpp/absl/base/internal/raw_logging.cc',
'third_party/abseil-cpp/absl/base/internal/spinlock.cc',
'third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc',
@ -484,9 +485,18 @@ CORE_SOURCE_FILES = [
'third_party/abseil-cpp/absl/base/internal/throw_delegate.cc',
'third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc',
'third_party/abseil-cpp/absl/base/log_severity.cc',
'third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc',
'third_party/abseil-cpp/absl/debugging/internal/demangle.cc',
'third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc',
'third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc',
'third_party/abseil-cpp/absl/debugging/stacktrace.cc',
'third_party/abseil-cpp/absl/debugging/symbolize.cc',
'third_party/abseil-cpp/absl/numeric/int128.cc',
'third_party/abseil-cpp/absl/status/status.cc',
'third_party/abseil-cpp/absl/status/status_payload_printer.cc',
'third_party/abseil-cpp/absl/strings/ascii.cc',
'third_party/abseil-cpp/absl/strings/charconv.cc',
'third_party/abseil-cpp/absl/strings/cord.cc',
'third_party/abseil-cpp/absl/strings/escaping.cc',
'third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc',
'third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc',

@ -13,7 +13,7 @@ py_library(
)
py_library(
name = "client",
name = "client_lib",
srcs = ["client.py"],
imports = ["../../"],
deps = [
@ -25,6 +25,13 @@ py_library(
],
)
py_binary(
name = "client",
srcs = ["client.py"],
python_version = "PY3",
deps = [":client_lib"],
)
py_library(
name = "methods",
srcs = ["methods.py"],

@ -51,6 +51,10 @@ def parse_interop_client_args():
default=False,
type=resources.parse_bool,
help='replace platform root CAs with ca.pem')
parser.add_argument('--custom_credentials_type',
choices=["compute_engine_channel_creds"],
default=None,
help='use google default credentials')
parser.add_argument('--server_host_override',
type=str,
help='the server host to which to claim to connect')
@ -60,6 +64,14 @@ def parse_interop_client_args():
parser.add_argument('--default_service_account',
type=str,
help='email address of the default service account')
parser.add_argument(
"--grpc_test_use_grpclb_with_child_policy",
type=str,
help=(
"If non-empty, set a static service config on channels created by "
+ "grpc::CreateTestChannel, that configures the grpclb LB policy " +
"with a child policy being the value of this flag (e.g. round_robin "
+ "or pick_first)."))
return parser.parse_args()
@ -89,8 +101,27 @@ def _create_call_credentials(args):
def get_secure_channel_parameters(args):
call_credentials = _create_call_credentials(args)
channel_opts = None
if args.use_tls:
channel_opts = ()
if args.grpc_test_use_grpclb_with_child_policy:
channel_opts += ((
"grpc.service_config",
'{"loadBalancingConfig": [{"grpclb": {"childPolicy": [{"%s": {}}]}}]}'
% args.grpc_test_use_grpclb_with_child_policy),)
if args.custom_credentials_type is not None:
if args.custom_credentials_type == "compute_engine_channel_creds":
assert call_credentials is None
google_credentials, unused_project_id = google_auth.default(
scopes=[args.oauth_scope])
call_creds = grpc.metadata_call_credentials(
google_auth.transport.grpc.AuthMetadataPlugin(
credentials=google_credentials,
request=google_auth.transport.requests.Request()))
channel_credentials = grpc.compute_engine_channel_credentials(
call_creds)
else:
raise ValueError("Unknown credentials type '{}'".format(
args.custom_credentials_type))
elif args.use_tls:
if args.use_test_ca:
root_certificates = resources.test_root_certificates()
else:
@ -102,7 +133,7 @@ def get_secure_channel_parameters(args):
channel_credentials, call_credentials)
if args.server_host_override:
channel_opts = ((
channel_opts += ((
'grpc.ssl_target_name_override',
args.server_host_override,
),)
@ -115,7 +146,7 @@ def get_secure_channel_parameters(args):
def _create_channel(args):
target = '{}:{}'.format(args.server_host, args.server_port)
if args.use_tls or args.use_alts:
if args.use_tls or args.use_alts or args.custom_credentials_type is not None:
channel_credentials, options = get_secure_channel_parameters(args)
return grpc.secure_channel(target, channel_credentials, options)
else:

@ -70,7 +70,7 @@ py_binary(
deps = [
":methods",
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_tests/tests/interop:client",
"//src/python/grpcio_tests/tests/interop:client_lib",
"//src/python/grpcio_tests/tests/interop:resources",
],
)

@ -30,7 +30,7 @@ _LOGGER.setLevel(logging.DEBUG)
def _create_channel(args):
target = f'{args.server_host}:{args.server_port}'
if args.use_tls or args.use_alts:
if args.use_tls or args.use_alts or args.custom_credentials_type is not None:
channel_credentials, options = interop_client_lib.get_secure_channel_parameters(
args)
return aio.secure_channel(target, channel_credentials, options)

@ -120,12 +120,12 @@ grpc_auth_context_set_peer_identity_property_name_type grpc_auth_context_set_pee
grpc_ssl_session_cache_create_lru_type grpc_ssl_session_cache_create_lru_import;
grpc_ssl_session_cache_destroy_type grpc_ssl_session_cache_destroy_import;
grpc_ssl_session_cache_create_channel_arg_type grpc_ssl_session_cache_create_channel_arg_import;
grpc_call_credentials_release_type grpc_call_credentials_release_import;
grpc_channel_credentials_release_type grpc_channel_credentials_release_import;
grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import;
grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
grpc_ssl_credentials_create_ex_type grpc_ssl_credentials_create_ex_import;
grpc_call_credentials_release_type grpc_call_credentials_release_import;
grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import;
grpc_composite_call_credentials_create_type grpc_composite_call_credentials_create_import;
grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import;
@ -394,12 +394,12 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_ssl_session_cache_create_lru_import = (grpc_ssl_session_cache_create_lru_type) GetProcAddress(library, "grpc_ssl_session_cache_create_lru");
grpc_ssl_session_cache_destroy_import = (grpc_ssl_session_cache_destroy_type) GetProcAddress(library, "grpc_ssl_session_cache_destroy");
grpc_ssl_session_cache_create_channel_arg_import = (grpc_ssl_session_cache_create_channel_arg_type) GetProcAddress(library, "grpc_ssl_session_cache_create_channel_arg");
grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release");
grpc_channel_credentials_release_import = (grpc_channel_credentials_release_type) GetProcAddress(library, "grpc_channel_credentials_release");
grpc_google_default_credentials_create_import = (grpc_google_default_credentials_create_type) GetProcAddress(library, "grpc_google_default_credentials_create");
grpc_set_ssl_roots_override_callback_import = (grpc_set_ssl_roots_override_callback_type) GetProcAddress(library, "grpc_set_ssl_roots_override_callback");
grpc_ssl_credentials_create_import = (grpc_ssl_credentials_create_type) GetProcAddress(library, "grpc_ssl_credentials_create");
grpc_ssl_credentials_create_ex_import = (grpc_ssl_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_credentials_create_ex");
grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release");
grpc_composite_channel_credentials_create_import = (grpc_composite_channel_credentials_create_type) GetProcAddress(library, "grpc_composite_channel_credentials_create");
grpc_composite_call_credentials_create_import = (grpc_composite_call_credentials_create_type) GetProcAddress(library, "grpc_composite_call_credentials_create");
grpc_google_compute_engine_credentials_create_import = (grpc_google_compute_engine_credentials_create_type) GetProcAddress(library, "grpc_google_compute_engine_credentials_create");

@ -335,10 +335,13 @@ extern grpc_ssl_session_cache_destroy_type grpc_ssl_session_cache_destroy_import
typedef grpc_arg(*grpc_ssl_session_cache_create_channel_arg_type)(grpc_ssl_session_cache* cache);
extern grpc_ssl_session_cache_create_channel_arg_type grpc_ssl_session_cache_create_channel_arg_import;
#define grpc_ssl_session_cache_create_channel_arg grpc_ssl_session_cache_create_channel_arg_import
typedef void(*grpc_call_credentials_release_type)(grpc_call_credentials* creds);
extern grpc_call_credentials_release_type grpc_call_credentials_release_import;
#define grpc_call_credentials_release grpc_call_credentials_release_import
typedef void(*grpc_channel_credentials_release_type)(grpc_channel_credentials* creds);
extern grpc_channel_credentials_release_type grpc_channel_credentials_release_import;
#define grpc_channel_credentials_release grpc_channel_credentials_release_import
typedef grpc_channel_credentials*(*grpc_google_default_credentials_create_type)(void);
typedef grpc_channel_credentials*(*grpc_google_default_credentials_create_type)(grpc_call_credentials* call_credentials);
extern grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
#define grpc_google_default_credentials_create grpc_google_default_credentials_create_import
typedef void(*grpc_set_ssl_roots_override_callback_type)(grpc_ssl_roots_override_callback cb);
@ -350,9 +353,6 @@ extern grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
typedef grpc_channel_credentials*(*grpc_ssl_credentials_create_ex_type)(const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const grpc_ssl_verify_peer_options* verify_options, void* reserved);
extern grpc_ssl_credentials_create_ex_type grpc_ssl_credentials_create_ex_import;
#define grpc_ssl_credentials_create_ex grpc_ssl_credentials_create_ex_import
typedef void(*grpc_call_credentials_release_type)(grpc_call_credentials* creds);
extern grpc_call_credentials_release_type grpc_call_credentials_release_import;
#define grpc_call_credentials_release grpc_call_credentials_release_import
typedef grpc_channel_credentials*(*grpc_composite_channel_credentials_create_type)(grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds, void* reserved);
extern grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import;
#define grpc_composite_channel_credentials_create grpc_composite_channel_credentials_create_import

@ -41,4 +41,5 @@
# Cloning from a local path sets RepositoryUrl to a path and breaks Source Link.
# Override RepositoryUrl to a URL to fix Source Link. The value doesn't matter.
dotnet build --configuration Debug Grpc.DotNet.sln -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git
dotnet build --configuration Debug --output ./output/InteropTestsWebsite testassets/InteropTestsWebsite/InteropTestsWebsite.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git
dotnet build --configuration Debug --output ./output/InteropTestsClient testassets/InteropTestsClient/InteropTestsClient.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git

@ -1347,16 +1347,24 @@ static void set_google_default_creds_env_var_with_file_contents(
gpr_free(creds_file_name);
}
static bool test_gce_tenancy_checker(void) {
g_test_gce_tenancy_checker_called = true;
return g_test_is_on_gce;
}
static void test_google_default_creds_auth_key(void) {
grpc_core::ExecCtx exec_ctx;
grpc_composite_channel_credentials* creds;
char* json_key = test_json_key_str();
grpc_flush_cached_google_default_credentials();
set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
g_test_gce_tenancy_checker_called = false;
g_test_is_on_gce = true;
set_google_default_creds_env_var_with_file_contents(
"json_key_google_default_creds", json_key);
gpr_free(json_key);
creds = reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
grpc_google_default_credentials_create(nullptr));
auto* default_creds =
reinterpret_cast<const grpc_google_default_channel_credentials*>(
creds->inner_creds());
@ -1368,6 +1376,7 @@ static void test_google_default_creds_auth_key(void) {
strcmp(jwt->key().client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
0);
GPR_ASSERT(g_test_gce_tenancy_checker_called == false);
creds->Unref();
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
}
@ -1379,7 +1388,7 @@ static void test_google_default_creds_refresh_token(void) {
set_google_default_creds_env_var_with_file_contents(
"refresh_token_google_default_creds", test_refresh_token_str);
creds = reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
grpc_google_default_credentials_create(nullptr));
auto* default_creds =
reinterpret_cast<const grpc_google_default_channel_credentials*>(
creds->inner_creds());
@ -1411,11 +1420,6 @@ static int default_creds_metadata_server_detection_httpcli_get_success_override(
static std::string null_well_known_creds_path_getter(void) { return ""; }
static bool test_gce_tenancy_checker(void) {
g_test_gce_tenancy_checker_called = true;
return g_test_is_on_gce;
}
static void test_google_default_creds_gce(void) {
grpc_core::ExecCtx exec_ctx;
expected_md emd[] = {
@ -1435,7 +1439,7 @@ static void test_google_default_creds_gce(void) {
/* Simulate a successful detection of GCE. */
grpc_composite_channel_credentials* creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
grpc_google_default_credentials_create(nullptr));
/* Verify that the default creds actually embeds a GCE creds. */
GPR_ASSERT(creds != nullptr);
@ -1474,7 +1478,7 @@ static void test_google_default_creds_non_gce(void) {
httpcli_post_should_not_be_called);
grpc_composite_channel_credentials* creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
grpc_google_default_credentials_create(nullptr));
/* Verify that the default creds actually embeds a GCE creds. */
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(creds->call_creds() != nullptr);
@ -1512,16 +1516,105 @@ static void test_no_google_default_creds(void) {
default_creds_gce_detection_httpcli_get_failure_override,
httpcli_post_should_not_be_called);
/* Simulate a successful detection of GCE. */
GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
GPR_ASSERT(grpc_google_default_credentials_create(nullptr) == nullptr);
/* Try a second one. GCE detection should occur again. */
g_test_gce_tenancy_checker_called = false;
GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
GPR_ASSERT(grpc_google_default_credentials_create(nullptr) == nullptr);
GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
/* Cleanup. */
grpc_override_well_known_credentials_path_getter(nullptr);
grpc_httpcli_set_override(nullptr, nullptr);
}
static void test_google_default_creds_call_creds_specified(void) {
expected_md emd[] = {
{"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
request_metadata_state* state =
make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr};
grpc_core::ExecCtx exec_ctx;
grpc_flush_cached_google_default_credentials();
grpc_call_credentials* call_creds =
grpc_google_compute_engine_credentials_create(nullptr);
set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
g_test_gce_tenancy_checker_called = false;
g_test_is_on_gce = true;
grpc_httpcli_set_override(
default_creds_metadata_server_detection_httpcli_get_success_override,
httpcli_post_should_not_be_called);
grpc_composite_channel_credentials* channel_creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create(call_creds));
GPR_ASSERT(g_test_gce_tenancy_checker_called == false);
GPR_ASSERT(channel_creds != nullptr);
GPR_ASSERT(channel_creds->call_creds() != nullptr);
grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
run_request_metadata_test(channel_creds->mutable_call_creds(), auth_md_ctx,
state);
grpc_core::ExecCtx::Get()->Flush();
channel_creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
}
struct fake_call_creds : public grpc_call_credentials {
public:
explicit fake_call_creds() : grpc_call_credentials("fake") {
grpc_slice key = grpc_slice_from_static_string("foo");
grpc_slice value = grpc_slice_from_static_string("oof");
dummy_md_ = grpc_mdelem_from_slices(key, value);
grpc_slice_unref(key);
grpc_slice_unref(value);
}
~fake_call_creds() { GRPC_MDELEM_UNREF(dummy_md_); }
bool get_request_metadata(grpc_polling_entity* pollent,
grpc_auth_metadata_context context,
grpc_credentials_mdelem_array* md_array,
grpc_closure* on_request_metadata,
grpc_error** error) {
grpc_credentials_mdelem_array_add(md_array, dummy_md_);
return true;
}
void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
grpc_error* error) {}
private:
grpc_mdelem dummy_md_;
};
static void test_google_default_creds_not_default(void) {
expected_md emd[] = {{"foo", "oof"}};
request_metadata_state* state =
make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr};
grpc_core::ExecCtx exec_ctx;
grpc_flush_cached_google_default_credentials();
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds =
grpc_core::MakeRefCounted<fake_call_creds>();
set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
g_test_gce_tenancy_checker_called = false;
g_test_is_on_gce = true;
grpc_httpcli_set_override(
default_creds_metadata_server_detection_httpcli_get_success_override,
httpcli_post_should_not_be_called);
grpc_composite_channel_credentials* channel_creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create(call_creds.release()));
GPR_ASSERT(g_test_gce_tenancy_checker_called == false);
GPR_ASSERT(channel_creds != nullptr);
GPR_ASSERT(channel_creds->call_creds() != nullptr);
run_request_metadata_test(channel_creds->mutable_call_creds(), auth_md_ctx,
state);
grpc_core::ExecCtx::Get()->Flush();
channel_creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
}
typedef enum {
PLUGIN_INITIAL_STATE,
PLUGIN_GET_METADATA_CALLED_STATE,
@ -1825,6 +1918,8 @@ int main(int argc, char** argv) {
test_google_default_creds_gce();
test_google_default_creds_non_gce();
test_no_google_default_creds();
test_google_default_creds_call_creds_specified();
test_google_default_creds_not_default();
test_metadata_plugin_success();
test_metadata_plugin_failure();
test_get_well_known_google_credentials_file_path();

@ -30,7 +30,8 @@
class Watcher : public grpc_core::ConnectivityStateWatcherInterface {
public:
void Notify(grpc_connectivity_state new_state) override {
void Notify(grpc_connectivity_state new_state,
const absl::Status& /* status */) override {
GPR_ASSERT(new_state == GRPC_CHANNEL_SHUTDOWN);
}
};

@ -164,12 +164,12 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) grpc_ssl_session_cache_create_lru);
printf("%lx", (unsigned long) grpc_ssl_session_cache_destroy);
printf("%lx", (unsigned long) grpc_ssl_session_cache_create_channel_arg);
printf("%lx", (unsigned long) grpc_call_credentials_release);
printf("%lx", (unsigned long) grpc_channel_credentials_release);
printf("%lx", (unsigned long) grpc_google_default_credentials_create);
printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback);
printf("%lx", (unsigned long) grpc_ssl_credentials_create);
printf("%lx", (unsigned long) grpc_ssl_credentials_create_ex);
printf("%lx", (unsigned long) grpc_call_credentials_release);
printf("%lx", (unsigned long) grpc_composite_channel_credentials_create);
printf("%lx", (unsigned long) grpc_composite_call_credentials_create);
printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create);

@ -65,7 +65,6 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server,
cq_verifier* cqv = cq_verifier_create(cq);
grpc_op ops[6];
grpc_op* op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
@ -78,7 +77,6 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server,
grpc_slice_from_static_string("/foo"), nullptr,
deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
@ -111,7 +109,6 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server,
cq_verify(cqv);
// cleanup
grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);

@ -42,116 +42,164 @@ TEST(ConnectivityStateName, Basic) {
class Watcher : public ConnectivityStateWatcherInterface {
public:
Watcher(int* count, grpc_connectivity_state* output,
Watcher(int* count, grpc_connectivity_state* output, absl::Status* status,
bool* destroyed = nullptr)
: count_(count), output_(output), destroyed_(destroyed) {}
: count_(count),
output_(output),
status_(status),
destroyed_(destroyed) {}
~Watcher() {
if (destroyed_ != nullptr) *destroyed_ = true;
}
void Notify(grpc_connectivity_state new_state) override {
void Notify(grpc_connectivity_state new_state,
const absl::Status& status) override {
++*count_;
*output_ = new_state;
*status_ = status;
}
private:
int* count_;
grpc_connectivity_state* output_;
absl::Status* status_;
bool* destroyed_;
};
TEST(StateTracker, SetAndGetState) {
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING);
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING,
absl::Status());
EXPECT_EQ(tracker.state(), GRPC_CHANNEL_CONNECTING);
tracker.SetState(GRPC_CHANNEL_READY, "whee");
EXPECT_TRUE(tracker.status().ok());
tracker.SetState(GRPC_CHANNEL_READY, absl::Status(), "whee");
EXPECT_EQ(tracker.state(), GRPC_CHANNEL_READY);
EXPECT_TRUE(tracker.status().ok());
absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
"status for testing");
tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status,
"reason");
EXPECT_EQ(tracker.state(), GRPC_CHANNEL_TRANSIENT_FAILURE);
EXPECT_EQ(tracker.status(), transient_failure_status);
}
TEST(StateTracker, NotificationUponAddingWatcher) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
MakeOrphanable<Watcher>(&count, &state));
MakeOrphanable<Watcher>(&count, &state, &status));
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING);
EXPECT_TRUE(status.ok());
}
TEST(StateTracker, NotificationUponAddingWatcherWithTransientFailure) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
"status for testing");
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_TRANSIENT_FAILURE,
transient_failure_status);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
MakeOrphanable<Watcher>(&count, &state, &status));
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE);
EXPECT_EQ(status, transient_failure_status);
}
TEST(StateTracker, NotificationUponStateChange) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
MakeOrphanable<Watcher>(&count, &state));
MakeOrphanable<Watcher>(&count, &state, &status));
EXPECT_EQ(count, 0);
EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
tracker.SetState(GRPC_CHANNEL_CONNECTING, "whee");
EXPECT_TRUE(status.ok());
absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
"status for testing");
tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status,
"whee");
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING);
EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE);
EXPECT_EQ(status, transient_failure_status);
}
TEST(StateTracker, SubscribeThenUnsubscribe) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
bool destroyed = false;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
ConnectivityStateWatcherInterface* watcher =
new Watcher(&count, &state, &destroyed);
new Watcher(&count, &state, &status, &destroyed);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
// No initial notification, since we started the watch from the
// current state.
EXPECT_EQ(count, 0);
EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
EXPECT_TRUE(status.ok());
// Cancel watch. This should not generate another notification.
tracker.RemoveWatcher(watcher);
EXPECT_TRUE(destroyed);
EXPECT_EQ(count, 0);
EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
EXPECT_TRUE(status.ok());
}
TEST(StateTracker, OrphanUponShutdown) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
bool destroyed = false;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
ConnectivityStateWatcherInterface* watcher =
new Watcher(&count, &state, &destroyed);
new Watcher(&count, &state, &status, &destroyed);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
// No initial notification, since we started the watch from the
// current state.
EXPECT_EQ(count, 0);
EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
EXPECT_TRUE(status.ok());
// Set state to SHUTDOWN.
tracker.SetState(GRPC_CHANNEL_SHUTDOWN, "shutting down");
tracker.SetState(GRPC_CHANNEL_SHUTDOWN, absl::Status(), "shutting down");
EXPECT_TRUE(destroyed);
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
EXPECT_TRUE(status.ok());
}
TEST(StateTracker, AddWhenAlreadyShutdown) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
bool destroyed = false;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN);
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN,
absl::Status());
ConnectivityStateWatcherInterface* watcher =
new Watcher(&count, &state, &destroyed);
new Watcher(&count, &state, &status, &destroyed);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
EXPECT_TRUE(destroyed);
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
EXPECT_TRUE(status.ok());
}
TEST(StateTracker, NotifyShutdownAtDestruction) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
absl::Status status;
{
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
MakeOrphanable<Watcher>(&count, &state));
MakeOrphanable<Watcher>(&count, &state, &status));
// No initial notification, since we started the watch from the
// current state.
EXPECT_EQ(count, 0);
@ -165,10 +213,11 @@ TEST(StateTracker, NotifyShutdownAtDestruction) {
TEST(StateTracker, DoNotNotifyShutdownAtDestructionIfAlreadyInShutdown) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
absl::Status status;
{
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN);
tracker.AddWatcher(GRPC_CHANNEL_SHUTDOWN,
MakeOrphanable<Watcher>(&count, &state));
MakeOrphanable<Watcher>(&count, &state, &status));
// No initial notification, since we started the watch from the
// current state.
EXPECT_EQ(count, 0);

@ -142,10 +142,10 @@ class TestPickArgsLb : public ForwardingLoadBalancingPolicy {
return parent_->channel_control_helper()->CreateSubchannel(args);
}
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override {
parent_->channel_control_helper()->UpdateState(
state, absl::make_unique<Picker>(std::move(picker), cb_));
state, status, absl::make_unique<Picker>(std::move(picker), cb_));
}
void RequestReresolution() override {
@ -252,10 +252,10 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy
return parent_->channel_control_helper()->CreateSubchannel(args);
}
void UpdateState(grpc_connectivity_state state,
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override {
parent_->channel_control_helper()->UpdateState(
state, absl::make_unique<Picker>(std::move(picker), cb_));
state, status, absl::make_unique<Picker>(std::move(picker), cb_));
}
void RequestReresolution() override {

@ -39,4 +39,5 @@ fi
# Cloning from a local path sets RepositoryUrl to a path and breaks Source Link.
# Override RepositoryUrl to a URL to fix Source Link. The value doesn't matter.
dotnet build --configuration Debug Grpc.DotNet.sln -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git
dotnet build --configuration Debug --output ./output/InteropTestsWebsite testassets/InteropTestsWebsite/InteropTestsWebsite.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git
dotnet build --configuration Debug --output ./output/InteropTestsClient testassets/InteropTestsClient/InteropTestsClient.csproj -p:RepositoryUrl=https://github.com/grpc/grpc-dotnet.git

@ -190,8 +190,8 @@ class CSharpCoreCLRLanguage:
class AspNetCoreLanguage:
def __init__(self):
self.client_cwd = '../grpc-dotnet/testassets/InteropTestsClient/bin/Debug/netcoreapp3.0'
self.server_cwd = '../grpc-dotnet/testassets/InteropTestsWebsite/bin/Debug/netcoreapp3.0'
self.client_cwd = '../grpc-dotnet/output/InteropTestsClient'
self.server_cwd = '../grpc-dotnet/output/InteropTestsWebsite'
self.safename = str(self)
def cloud_to_prod_env(self):

Loading…
Cancel
Save