Merge https://github.com/grpc/grpc into port_platform-src-core-clang-format

pull/36284/head
Craig Tiller 8 months ago
commit 99a9af9beb
  1. 3
      .clang-format
  2. 177
      CMakeLists.txt
  3. 58
      build_autogenerated.yaml
  4. 42
      examples/cpp/health/BUILD
  5. 98
      examples/cpp/health/CMakeLists.txt
  6. 6
      examples/cpp/health/README.md
  7. 140
      examples/cpp/health/health_client.cc
  8. 100
      examples/cpp/health/health_server.cc
  9. 3
      include/grpc++/impl/.clang-format
  10. 3
      include/grpc/.clang-format
  11. 3
      include/grpc/byte_buffer.h
  12. 3
      include/grpc/census.h
  13. 3
      include/grpc/compression.h
  14. 4
      include/grpc/event_engine/endpoint_config.h
  15. 3
      include/grpc/event_engine/event_engine.h
  16. 4
      include/grpc/event_engine/extensible.h
  17. 3
      include/grpc/event_engine/internal/memory_allocator_impl.h
  18. 3
      include/grpc/event_engine/memory_allocator.h
  19. 4
      include/grpc/event_engine/memory_request.h
  20. 3
      include/grpc/event_engine/slice.h
  21. 3
      include/grpc/event_engine/slice_buffer.h
  22. 3
      include/grpc/grpc.h
  23. 3
      include/grpc/grpc_audit_logging.h
  24. 3
      include/grpc/grpc_crl_provider.h
  25. 3
      include/grpc/grpc_cronet.h
  26. 3
      include/grpc/grpc_posix.h
  27. 3
      include/grpc/grpc_security.h
  28. 3
      include/grpc/impl/call.h
  29. 3
      include/grpc/impl/grpc_types.h
  30. 4
      include/grpc/impl/slice_type.h
  31. 3
      include/grpc/slice.h
  32. 3
      include/grpc/slice_buffer.h
  33. 4
      include/grpc/support/alloc.h
  34. 4
      include/grpc/support/json.h
  35. 4
      include/grpc/support/log.h
  36. 4
      include/grpc/support/metrics.h
  37. 1
      include/grpc/support/string_util.h
  38. 1
      include/grpc/support/sync.h
  39. 1
      include/grpc/support/sync_abseil.h
  40. 1
      include/grpc/support/sync_custom.h
  41. 3
      include/grpc/support/sync_generic.h
  42. 3
      include/grpc/support/sync_posix.h
  43. 4
      include/grpc/support/time.h
  44. 3
      include/grpcpp/.clang-format
  45. 3
      include/grpcpp/create_channel_posix.h
  46. 1
      include/grpcpp/ext/channelz_service_plugin.h
  47. 3
      include/grpcpp/ext/csm_observability.h
  48. 3
      include/grpcpp/ext/gcp_observability.h
  49. 3
      include/grpcpp/ext/otel_plugin.h
  50. 3
      include/grpcpp/ext/server_load_reporting.h
  51. 1
      include/grpcpp/generic/async_generic_service.h
  52. 3
      include/grpcpp/impl/.clang-format
  53. 3
      include/grpcpp/impl/codegen/.clang-format
  54. 3
      include/grpcpp/impl/status.h
  55. 3
      include/grpcpp/security/.clang-format
  56. 3
      include/grpcpp/server.h
  57. 3
      include/grpcpp/server_builder.h
  58. 3
      include/grpcpp/server_context.h
  59. 3
      include/grpcpp/server_interface.h
  60. 3
      include/grpcpp/server_posix.h
  61. 1
      include/grpcpp/xds_server_builder.h
  62. 3
      src/compiler/.clang-format
  63. 2
      src/core/BUILD
  64. 269
      src/core/ext/xds/xds_client.cc
  65. 12
      src/core/ext/xds/xds_client.h
  66. 4
      src/core/ext/xds/xds_client_grpc.cc
  67. 8
      src/core/lib/promise/status_flag.h
  68. 118
      src/core/lib/transport/call_filters.cc
  69. 299
      src/core/lib/transport/call_filters.h
  70. 5
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
  71. 53
      src/python/grpcio_tests/tests/unit/_api_test.py
  72. 4
      test/core/address_utils/sockaddr_utils_test.cc
  73. 3
      test/core/client_channel/client_channel_test.cc
  74. 3
      test/core/client_channel/lb_policy/lb_policy_test_lib.h
  75. 4
      test/core/compiler_bugs/miscompile_with_no_unique_address_test.cc
  76. 4
      test/core/end2end/BUILD
  77. 60
      test/core/end2end/end2end_test_fuzzer.cc
  78. 24
      test/core/end2end/end2end_test_fuzzer.h
  79. 20
      test/core/end2end/end2end_test_fuzzer_main.cc
  80. 6
      test/core/end2end/grpc_core_end2end_test.bzl
  81. 3
      test/core/end2end/invalid_call_argument_test.cc
  82. 4
      test/core/event_engine/common_closures_test.cc
  83. 3
      test/core/event_engine/default_engine_methods_test.cc
  84. 4
      test/core/event_engine/endpoint_config_test.cc
  85. 3
      test/core/event_engine/factory_test.cc
  86. 4
      test/core/event_engine/forkable_test.cc
  87. 4
      test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine_unittest.cc
  88. 3
      test/core/event_engine/handle_tests.cc
  89. 3
      test/core/event_engine/query_extensions_test.cc
  90. 3
      test/core/event_engine/slice_buffer_test.cc
  91. 3
      test/core/event_engine/smoke_test.cc
  92. 4
      test/core/event_engine/tcp_socket_utils_test.cc
  93. 4
      test/core/event_engine/test_init.cc
  94. 4
      test/core/event_engine/test_init.h
  95. 3
      test/core/event_engine/test_suite/tests/dns_test.cc
  96. 3
      test/core/event_engine/test_suite/tools/echo_client.cc
  97. 3
      test/core/event_engine/test_suite/tools/posix_event_engine_factory.cc
  98. 3
      test/core/event_engine/test_suite/tools/windows_event_engine_factory.cc
  99. 3
      test/core/event_engine/util/aborting_event_engine.h
  100. 3
      test/core/event_engine/work_queue/basic_work_queue_fuzzer.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

177
CMakeLists.txt generated

@ -1557,6 +1557,9 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx xds_end2end_test)
endif()
add_dependencies(buildtests_cxx xds_endpoint_resource_type_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx xds_fallback_end2end_test)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx xds_fault_injection_end2end_test)
endif()
@ -34244,6 +34247,180 @@ target_link_libraries(xds_endpoint_resource_type_test
)
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(xds_fallback_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/expr.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/expr.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/expr.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/expr.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_filter_rbac.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_filter_rbac.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_filter_rbac.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_filter_rbac.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/metadata.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/metadata.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/metadata.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/metadata.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/path.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/path.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/path.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/path.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/rbac.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/rbac.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/rbac.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/rbac.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
test/cpp/end2end/xds/xds_fallback_end2end_test.cc
test/cpp/end2end/xds/xds_server.cc
test/cpp/end2end/xds/xds_utils.cc
test/cpp/util/tls_test_utils.cc
)
if(WIN32 AND MSVC)
if(BUILD_SHARED_LIBS)
target_compile_definitions(xds_fallback_end2end_test
PRIVATE
"GPR_DLL_IMPORTS"
"GRPC_DLL_IMPORTS"
"GRPCXX_DLL_IMPORTS"
)
endif()
endif()
target_compile_features(xds_fallback_end2end_test PUBLIC cxx_std_14)
target_include_directories(xds_fallback_end2end_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(xds_fallback_end2end_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
grpc++_test_util
)
endif()
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)

@ -6411,6 +6411,7 @@ targets:
- src/core/lib/promise/detail/seq_state.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/latch.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
@ -20860,6 +20861,63 @@ targets:
- protobuf
- grpc_test_util
uses_polling: false
- name: xds_fallback_end2end_test
gtest: true
build: test
language: c++
headers:
- test/core/util/scoped_env_var.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_end2end_test_lib.h
- test/cpp/end2end/xds/xds_server.h
- test/cpp/end2end/xds/xds_utils.h
- test/cpp/util/tls_test_utils.h
src:
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/simple_messages.proto
- src/proto/grpc/testing/xds/v3/address.proto
- src/proto/grpc/testing/xds/v3/ads.proto
- src/proto/grpc/testing/xds/v3/base.proto
- src/proto/grpc/testing/xds/v3/cluster.proto
- src/proto/grpc/testing/xds/v3/config_source.proto
- src/proto/grpc/testing/xds/v3/discovery.proto
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
- src/proto/grpc/testing/xds/v3/load_report.proto
- src/proto/grpc/testing/xds/v3/lrs.proto
- src/proto/grpc/testing/xds/v3/metadata.proto
- src/proto/grpc/testing/xds/v3/orca_load_report.proto
- src/proto/grpc/testing/xds/v3/outlier_detection.proto
- src/proto/grpc/testing/xds/v3/path.proto
- src/proto/grpc/testing/xds/v3/percent.proto
- src/proto/grpc/testing/xds/v3/protocol.proto
- src/proto/grpc/testing/xds/v3/range.proto
- src/proto/grpc/testing/xds/v3/rbac.proto
- src/proto/grpc/testing/xds/v3/regex.proto
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
- test/cpp/end2end/xds/xds_fallback_end2end_test.cc
- test/cpp/end2end/xds/xds_server.cc
- test/cpp/end2end/xds/xds_utils.cc
- test/cpp/util/tls_test_utils.cc
deps:
- gtest
- grpc++_test_util
platforms:
- linux
- posix
- mac
- name: xds_fault_injection_end2end_test
gtest: true
build: test

@ -0,0 +1,42 @@
# Copyright 2024 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "health_client",
srcs = ["health_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
"//src/proto/grpc/health/v1:health_proto",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
],
)
cc_binary(
name = "health_server",
srcs = ["health_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//:grpc++_reflection",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
"@com_google_absl//absl/strings:str_format",
],
)

@ -0,0 +1,98 @@
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# cmake build file for C++ helloworld example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building helloworld.
cmake_minimum_required(VERSION 3.8)
project(HelloWorld C CXX)
include(../cmake/common.cmake)
# Proto file
get_filename_component(hw_proto "../../protos/helloworld.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
get_filename_component(health_proto "../../../src/proto/grpc/health/v1/health.proto" ABSOLUTE)
get_filename_component(health_proto_path "${health_proto}" PATH)
# Generated sources
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h")
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${hw_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
# Health protos
set(health_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/health.pb.cc")
set(health_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/health.pb.h")
set(health_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/health.grpc.pb.cc")
set(health_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/health.grpc.pb.h")
add_custom_command(
OUTPUT "${health_proto_srcs}" "${health_proto_hdrs}" "${health_grpc_srcs}" "${health_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${health_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${health_proto}"
DEPENDS "${health_proto}")
# Include generated *.pb.h files
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# hw_grpc_proto
add_library(hw_grpc_proto
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto_srcs}
${hw_proto_hdrs})
target_link_libraries(hw_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
#health_grpc_proto
add_library(health_grpc_proto
${health_grpc_srcs}
${health_grpc_hdrs}
${health_proto_srcs}
${health_proto_hdrs})
target_link_libraries(health_grpc_proto
${_PROTOBUF_LIBPROTOBUF})
# Targets greeter_[async_](client|server)
foreach(_target
health_client health_server)
add_executable(${_target} "${_target}.cc")
target_link_libraries(${_target}
hw_grpc_proto
health_grpc_proto
absl::flags
absl::flags_parse
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
endforeach()

@ -0,0 +1,6 @@
# gRPC C++ Health Check Example
You can find a complete set of instructions for building gRPC and running the
example in the [C++ Quick Start][].
[C++ Quick Start]: https://grpc.io/docs/languages/cpp/quickstart

@ -0,0 +1,140 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#include "src/proto/grpc/health/v1/health.grpc.pb.h"
#else
#include "health.grpc.pb.h"
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(std::string, target, "localhost:50051", "Server address");
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc::health::v1::Health;
using grpc::health::v1::HealthCheckRequest;
using grpc::health::v1::HealthCheckResponse;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)),
health_stub_(Health::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
std::mutex mu;
std::condition_variable cv;
bool done = false;
Status status;
stub_->async()->SayHello(&context, &request, &reply,
[&mu, &cv, &done, &status](Status s) {
status = std::move(s);
std::lock_guard<std::mutex> lock(mu);
done = true;
cv.notify_one();
});
std::unique_lock<std::mutex> lock(mu);
while (!done) {
cv.wait(lock);
}
// Act upon its status.
if (status.ok()) {
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}
void CheckHealth(const std::string& message) {
ClientContext context;
HealthCheckResponse response;
Status status = health_stub_->Check(
&context, HealthCheckRequest::default_instance(), &response);
if (!status.ok()) {
std::cerr << "Failed to check service health: " << status.error_code()
<< ": " << status.error_message() << "\n";
return;
}
std::cout << message << ": " << response.DebugString();
}
private:
std::unique_ptr<Greeter::Stub> stub_;
std::unique_ptr<Health::Stub> health_stub_;
};
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
std::string target_str = absl::GetFlag(FLAGS_target);
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
grpc::ChannelArguments args;
args.SetServiceConfigJSON(
"{\"healthCheckConfig\": "
"{\"serviceName\": \"\"}}");
GreeterClient greeter(grpc::CreateCustomChannel(
target_str, grpc::InsecureChannelCredentials(), args));
std::string user = "world";
greeter.CheckHealth("Before call");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
greeter.CheckHealth("After call");
reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
greeter.CheckHealth("After second call");
return 0;
}

@ -0,0 +1,100 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <iostream>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(uint16_t, port, 50051, "Server port for the service");
using grpc::CallbackServerContext;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerUnaryReactor;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::CallbackService {
public:
void set_health_check_service(
grpc::HealthCheckServiceInterface* health_check_service) {
health_check_service_ = health_check_service;
}
private:
ServerUnaryReactor* SayHello(CallbackServerContext* context,
const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
ServerUnaryReactor* reactor = context->DefaultReactor();
reactor->Finish(Status::OK);
// Goes down, then up
is_serving_ = !is_serving_;
health_check_service_->SetServingStatus(is_serving_);
return reactor;
}
grpc::HealthCheckServiceInterface* health_check_service_ = nullptr;
bool is_serving_ = true;
};
void RunServer(uint16_t port) {
std::string server_address = absl::StrFormat("0.0.0.0:%d", port);
GreeterServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
service.set_health_check_service(server->GetHealthCheckService());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -19,10 +19,9 @@
#ifndef GRPC_BYTE_BUFFER_H
#define GRPC_BYTE_BUFFER_H
#include <grpc/support/port_platform.h>
#include <grpc/impl/grpc_types.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -19,9 +19,8 @@
#ifndef GRPC_CENSUS_H
#define GRPC_CENSUS_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -19,12 +19,11 @@
#ifndef GRPC_COMPRESSION_H
#define GRPC_COMPRESSION_H
#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <grpc/impl/compression_types.h> // IWYU pragma: export
#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -14,13 +14,13 @@
#ifndef GRPC_EVENT_ENGINE_ENDPOINT_CONFIG_H
#define GRPC_EVENT_ENGINE_ENDPOINT_CONFIG_H
#include <grpc/support/port_platform.h>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -14,8 +14,6 @@
#ifndef GRPC_EVENT_ENGINE_EVENT_ENGINE_H
#define GRPC_EVENT_ENGINE_EVENT_ENGINE_H
#include <grpc/support/port_platform.h>
#include <vector>
#include "absl/functional/any_invocable.h"
@ -27,6 +25,7 @@
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/event_engine/port.h>
#include <grpc/event_engine/slice_buffer.h>
#include <grpc/support/port_platform.h>
// TODO(vigneshbabu): Define the Endpoint::Write metrics collection system
namespace grpc_event_engine {

@ -15,10 +15,10 @@
#ifndef GRPC_EVENT_ENGINE_EXTENSIBLE_H
#define GRPC_EVENT_ENGINE_EXTENSIBLE_H
#include <grpc/support/port_platform.h>
#include "absl/strings/string_view.h"
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -14,8 +14,6 @@
#ifndef GRPC_EVENT_ENGINE_INTERNAL_MEMORY_ALLOCATOR_IMPL_H
#define GRPC_EVENT_ENGINE_INTERNAL_MEMORY_ALLOCATOR_IMPL_H
#include <grpc/support/port_platform.h>
#include <algorithm>
#include <memory>
#include <type_traits>
@ -23,6 +21,7 @@
#include <grpc/event_engine/memory_request.h>
#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -14,8 +14,6 @@
#ifndef GRPC_EVENT_ENGINE_MEMORY_ALLOCATOR_H
#define GRPC_EVENT_ENGINE_MEMORY_ALLOCATOR_H
#include <grpc/support/port_platform.h>
#include <stdlib.h> // for abort()
#include <algorithm>
@ -25,6 +23,7 @@
#include <grpc/event_engine/internal/memory_allocator_impl.h>
#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -14,12 +14,12 @@
#ifndef GRPC_EVENT_ENGINE_MEMORY_REQUEST_H
#define GRPC_EVENT_ENGINE_MEMORY_REQUEST_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include "absl/strings/string_view.h"
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -15,8 +15,6 @@
#ifndef GRPC_EVENT_ENGINE_SLICE_H
#define GRPC_EVENT_ENGINE_SLICE_H
#include <grpc/support/port_platform.h>
#include <string.h>
#include <cstdint>
@ -28,6 +26,7 @@
#include <grpc/event_engine/internal/slice_cast.h>
#include <grpc/slice.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
// This public slice definition largely based of the internal grpc_core::Slice
// implementation. Changes to this implementation might warrant changes to the

@ -15,8 +15,6 @@
#ifndef GRPC_EVENT_ENGINE_SLICE_BUFFER_H
#define GRPC_EVENT_ENGINE_SLICE_BUFFER_H
#include <grpc/support/port_platform.h>
#include <string.h>
#include <cstdint>
@ -31,6 +29,7 @@
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -19,8 +19,6 @@
#ifndef GRPC_GRPC_H
#define GRPC_GRPC_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <grpc/byte_buffer.h>
@ -29,6 +27,7 @@
#include <grpc/impl/propagation_bits.h>
#include <grpc/slice.h>
#include <grpc/status.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#ifdef __cplusplus

@ -19,8 +19,6 @@
#ifndef GRPC_GRPC_AUDIT_LOGGING_H
#define GRPC_GRPC_AUDIT_LOGGING_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <string>
@ -28,6 +26,7 @@
#include "absl/strings/string_view.h"
#include <grpc/support/json.h>
#include <grpc/support/port_platform.h>
namespace grpc_core {
namespace experimental {

@ -19,8 +19,6 @@
#ifndef GRPC_GRPC_CRL_PROVIDER_H
#define GRPC_GRPC_CRL_PROVIDER_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <string>
@ -28,6 +26,7 @@
#include "absl/strings/string_view.h"
#include <grpc/grpc_security.h>
#include <grpc/support/port_platform.h>
namespace grpc_core {
namespace experimental {

@ -19,9 +19,8 @@
#ifndef GRPC_GRPC_CRONET_H
#define GRPC_GRPC_CRONET_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -19,12 +19,11 @@
#ifndef GRPC_GRPC_POSIX_H
#define GRPC_GRPC_POSIX_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <grpc/grpc.h>
#include <grpc/impl/grpc_types.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -19,13 +19,12 @@
#ifndef GRPC_GRPC_SECURITY_H
#define GRPC_GRPC_SECURITY_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security_constants.h>
#include <grpc/status.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -15,11 +15,10 @@
#ifndef GRPC_IMPL_CALL_H
#define GRPC_IMPL_CALL_H
#include <grpc/support/port_platform.h>
#include "absl/functional/any_invocable.h"
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
// Run a callback in the call's EventEngine.
// Internal-only

@ -21,14 +21,13 @@
// IWYU pragma: private, include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <grpc/impl/channel_arg_names.h>
#include <grpc/impl/compression_types.h>
#include <grpc/slice.h>
#include <grpc/status.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#ifdef __cplusplus

@ -21,10 +21,10 @@
// IWYU pragma: private, include <grpc/slice.h>
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <grpc/support/port_platform.h>
typedef struct grpc_slice grpc_slice;
/** Slice API

@ -19,9 +19,8 @@
#ifndef GRPC_SLICE_H
#define GRPC_SLICE_H
#include <grpc/support/port_platform.h>
#include <grpc/impl/slice_type.h> // IWYU pragma: export
#include <grpc/support/port_platform.h>
#include <grpc/support/sync.h>
#ifdef __cplusplus

@ -19,9 +19,8 @@
#ifndef GRPC_SLICE_BUFFER_H
#define GRPC_SLICE_BUFFER_H
#include <grpc/support/port_platform.h>
#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -19,10 +19,10 @@
#ifndef GRPC_SUPPORT_ALLOC_H
#define GRPC_SUPPORT_ALLOC_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {
#endif

@ -17,8 +17,6 @@
#ifndef GRPC_SUPPORT_JSON_H
#define GRPC_SUPPORT_JSON_H
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include <map>
@ -29,6 +27,8 @@
#include "absl/strings/str_cat.h"
#include "absl/types/variant.h"
#include <grpc/support/port_platform.h>
namespace grpc_core {
namespace experimental {

@ -19,11 +19,11 @@
#ifndef GRPC_SUPPORT_LOG_H
#define GRPC_SUPPORT_LOG_H
#include <grpc/support/port_platform.h>
#include <stdarg.h>
#include <stdlib.h> /* for abort() */
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {
#endif

@ -15,10 +15,10 @@
#ifndef GRPC_SUPPORT_METRICS_H
#define GRPC_SUPPORT_METRICS_H
#include <grpc/support/port_platform.h>
#include "absl/strings/string_view.h"
#include <grpc/support/port_platform.h>
namespace grpc_core {
namespace experimental {

@ -20,7 +20,6 @@
#define GRPC_SUPPORT_STRING_UTIL_H
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#ifdef __cplusplus

@ -21,7 +21,6 @@
/* Platform-specific type declarations of gpr_mu and gpr_cv. */
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h> /* for gpr_timespec */
#ifdef __cplusplus

@ -20,7 +20,6 @@
#define GRPC_SUPPORT_SYNC_ABSEIL_H
#include <grpc/support/port_platform.h>
#include <grpc/support/sync_generic.h>
#ifdef GPR_ABSEIL_SYNC

@ -20,7 +20,6 @@
#define GRPC_SUPPORT_SYNC_CUSTOM_H
#include <grpc/support/port_platform.h>
#include <grpc/support/sync_generic.h>
/* Users defining GPR_CUSTOM_SYNC need to define the following macros. */

@ -21,9 +21,8 @@
/* Generic type definitions for gpr_sync. */
#include <grpc/support/port_platform.h>
#include <grpc/support/atm.h>
#include <grpc/support/port_platform.h>
/* gpr_event */
typedef struct {

@ -19,10 +19,9 @@
#ifndef GRPC_SUPPORT_SYNC_POSIX_H
#define GRPC_SUPPORT_SYNC_POSIX_H
#include <grpc/support/port_platform.h>
#include <pthread.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/sync_generic.h>
#ifdef GRPC_ASAN_ENABLED

@ -19,11 +19,11 @@
#ifndef GRPC_SUPPORT_TIME_H
#define GRPC_SUPPORT_TIME_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <time.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {
#endif

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -19,10 +19,9 @@
#ifndef GRPCPP_CREATE_CHANNEL_POSIX_H
#define GRPCPP_CREATE_CHANNEL_POSIX_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <grpc/support/port_platform.h>
#include <grpcpp/channel.h>
#include <grpcpp/support/channel_arguments.h>

@ -20,7 +20,6 @@
#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/impl/server_initializer.h>
#include <grpcpp/support/config.h>

@ -19,8 +19,6 @@
#ifndef GRPCPP_EXT_CSM_OBSERVABILITY_H
#define GRPCPP_EXT_CSM_OBSERVABILITY_H
#include <grpc/support/port_platform.h>
#include <memory>
#include "absl/functional/any_invocable.h"
@ -28,6 +26,7 @@
#include "absl/strings/string_view.h"
#include "opentelemetry/metrics/meter_provider.h"
#include <grpc/support/port_platform.h>
#include <grpcpp/ext/otel_plugin.h>
namespace grpc {

@ -17,11 +17,10 @@
#ifndef GRPCPP_EXT_GCP_OBSERVABILITY_H
#define GRPCPP_EXT_GCP_OBSERVABILITY_H
#include <grpc/support/port_platform.h>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/grpc_library.h>
namespace grpc {

@ -19,8 +19,6 @@
#ifndef GRPCPP_EXT_OTEL_PLUGIN_H
#define GRPCPP_EXT_OTEL_PLUGIN_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <stdint.h>
@ -32,6 +30,7 @@
#include "opentelemetry/metrics/meter_provider.h"
#include <grpc/support/metrics.h>
#include <grpc/support/port_platform.h>
namespace grpc {

@ -19,9 +19,8 @@
#ifndef GRPCPP_EXT_SERVER_LOAD_REPORTING_H
#define GRPCPP_EXT_SERVER_LOAD_REPORTING_H
#include <grpc/support/port_platform.h>
#include <grpc/load_reporting.h>
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/server_builder_option.h>
#include <grpcpp/server_context.h>
#include <grpcpp/support/config.h>

@ -20,7 +20,6 @@
#define GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/server_callback_handlers.h>
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/byte_buffer.h>

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -21,9 +21,8 @@
// IWYU pragma: private, include <grpcpp/support/status.h>
#include <grpc/support/port_platform.h>
#include <grpc/status.h>
#include <grpc/support/port_platform.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/status_code_enum.h>

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -19,14 +19,13 @@
#ifndef GRPCPP_SERVER_H
#define GRPCPP_SERVER_H
#include <grpc/support/port_platform.h>
#include <list>
#include <memory>
#include <vector>
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpc/support/port_platform.h>
#include <grpcpp/channel.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/health_check_service_interface.h>

@ -19,8 +19,6 @@
#ifndef GRPCPP_SERVER_BUILDER_H
#define GRPCPP_SERVER_BUILDER_H
#include <grpc/support/port_platform.h>
#include <climits>
#include <map>
#include <memory>
@ -28,6 +26,7 @@
#include <grpc/compression.h>
#include <grpc/support/cpu.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/workaround_list.h>
#include <grpcpp/impl/channel_argument_option.h>
#include <grpcpp/impl/server_builder_option.h>

@ -19,8 +19,6 @@
#ifndef GRPCPP_SERVER_CONTEXT_H
#define GRPCPP_SERVER_CONTEXT_H
#include <grpc/support/port_platform.h>
#include <atomic>
#include <cassert>
#include <map>
@ -31,6 +29,7 @@
#include <grpc/grpc.h>
#include <grpc/impl/call.h>
#include <grpc/impl/compression_types.h>
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/call_op_set.h>
#include <grpcpp/impl/codegen/create_auth_context.h>

@ -19,11 +19,10 @@
#ifndef GRPCPP_SERVER_INTERFACE_H
#define GRPCPP_SERVER_INTERFACE_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/impl/grpc_types.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/call_hook.h>

@ -19,10 +19,9 @@
#ifndef GRPCPP_SERVER_POSIX_H
#define GRPCPP_SERVER_POSIX_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <grpc/support/port_platform.h>
#include <grpcpp/server.h>
namespace grpc {

@ -20,7 +20,6 @@
#define GRPCPP_XDS_SERVER_BUILDER_H
#include <grpc/support/port_platform.h>
#include <grpcpp/server_builder.h>
namespace grpc {

@ -5,9 +5,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
# port_platform.h is before almost everything
- Regex: '^<grpc/(support|impl/codegen)/port_platform.h>'
Priority: -100
# ruby.h is even more first if it's included
- Regex: '^<ruby/ruby.h>'
Priority: -200

@ -7252,6 +7252,8 @@ grpc_cc_library(
],
deps = [
"call_final_info",
"latch",
"map",
"message",
"metadata",
"ref_counted",

@ -24,7 +24,9 @@
#include <algorithm>
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/cleanup/cleanup.h"
#include "absl/strings/match.h"
@ -555,6 +557,67 @@ void XdsClient::XdsChannel::UnsubscribeLocked(const XdsResourceType* type,
}
}
bool XdsClient::XdsChannel::MaybeFallbackLocked(
const std::string& authority, AuthorityState& authority_state) {
if (!xds_client_->HasUncachedResources(authority_state)) {
return false;
}
std::vector<const XdsBootstrap::XdsServer*> xds_servers;
if (authority != kOldStyleAuthority) {
xds_servers =
xds_client_->bootstrap().LookupAuthority(authority)->servers();
}
if (xds_servers.empty()) xds_servers = xds_client_->bootstrap().servers();
for (size_t i = authority_state.xds_channels.size(); i < xds_servers.size();
++i) {
authority_state.xds_channels.emplace_back(
xds_client_->GetOrCreateXdsChannelLocked(*xds_servers[i], "fallback"));
for (const auto& type_resource : authority_state.resource_map) {
for (const auto& key_state : type_resource.second) {
authority_state.xds_channels.back()->SubscribeLocked(
type_resource.first, {authority, key_state.first});
}
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
"[xds_client %p] authority %s: added fallback server %s (%s)",
xds_client_.get(), authority.c_str(),
xds_servers[i]->server_uri().c_str(),
authority_state.xds_channels.back()->status().ToString().c_str());
}
if (authority_state.xds_channels.back()->status().ok()) return true;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO, "[xds_client %p] authority %s: No fallback server",
xds_client_.get(), authority.c_str());
}
return false;
}
void XdsClient::XdsChannel::SetHealthyLocked() {
status_ = absl::OkStatus();
// Make this channel active iff:
// 1. Channel is on the list of authority channels
// 2. Channel is not the last channel on the list (i.e. not the active
// channel)
for (auto& authority : xds_client_->authority_state_map_) {
auto& channels = authority.second.xds_channels;
// Skip if channel is active.
if (channels.back() == this) continue;
auto channel_it = std::find(channels.begin(), channels.end(), this);
// Skip if this is not on the list
if (channel_it != channels.end()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO, "[xds_client %p] authority %s: Falling forward to %s",
xds_client_.get(), authority.first.c_str(),
server_.server_uri().c_str());
}
// Lower priority channels are no longer needed, connection is back!
channels.erase(channel_it + 1, channels.end());
}
}
}
void XdsClient::XdsChannel::OnConnectivityFailure(absl::Status status) {
{
MutexLock lock(&xds_client_->mu_);
@ -584,8 +647,11 @@ void XdsClient::XdsChannel::SetChannelStatusLocked(absl::Status status) {
status_ = status;
// Find all watchers for this channel.
std::set<RefCountedPtr<ResourceWatcherInterface>> watchers;
for (const auto& a : xds_client_->authority_state_map_) { // authority
if (a.second.xds_channel != this) continue;
for (auto& a : xds_client_->authority_state_map_) { // authority
if (a.second.xds_channels.empty() || a.second.xds_channels.back() != this ||
MaybeFallbackLocked(a.first, a.second)) {
continue;
}
for (const auto& t : a.second.resource_map) { // type
for (const auto& r : t.second) { // resource id
for (const auto& w : r.second.watchers) { // watchers
@ -594,15 +660,17 @@ void XdsClient::XdsChannel::SetChannelStatusLocked(absl::Status status) {
}
}
}
// Enqueue notification for the watchers.
xds_client_->work_serializer_.Schedule(
[watchers = std::move(watchers), status = std::move(status)]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(xds_client_->work_serializer_) {
for (const auto& watcher : watchers) {
watcher->OnError(status, ReadDelayHandle::NoWait());
}
},
DEBUG_LOCATION);
if (!watchers.empty()) {
// Enqueue notification for the watchers.
xds_client_->work_serializer_.Schedule(
[watchers = std::move(watchers), status = std::move(status)]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(xds_client_->work_serializer_) {
for (const auto& watcher : watchers) {
watcher->OnError(status, ReadDelayHandle::NoWait());
}
},
DEBUG_LOCATION);
}
}
//
@ -955,10 +1023,13 @@ XdsClient::XdsChannel::AdsCall::AdsCall(
}
// If this is a reconnect, add any necessary subscriptions from what's
// already in the cache.
for (const auto& a : xds_client()->authority_state_map_) {
for (auto& a : xds_client()->authority_state_map_) {
const std::string& authority = a.first;
// Skip authorities that are not using this xDS channel.
if (a.second.xds_channel != xds_channel()) continue;
auto it = std::find(a.second.xds_channels.begin(),
a.second.xds_channels.end(), xds_channel());
// Skip authorities that are not using this xDS channel. The channel can be
// anywhere in the list.
if (it == a.second.xds_channels.end()) continue;
for (const auto& t : a.second.resource_map) {
const XdsResourceType* type = t.first;
for (const auto& r : t.second) {
@ -1097,7 +1168,7 @@ void XdsClient::XdsChannel::AdsCall::OnRecvMessage(absl::string_view payload) {
status.ToString().c_str());
} else {
seen_response_ = true;
xds_channel()->status_ = absl::OkStatus();
xds_channel()->SetHealthyLocked();
// Update nonce.
auto& state = state_map_[result.type];
state.nonce = result.nonce;
@ -1120,7 +1191,9 @@ void XdsClient::XdsChannel::AdsCall::OnRecvMessage(absl::string_view payload) {
const std::string& authority = a.first;
AuthorityState& authority_state = a.second;
// Skip authorities that are not using this xDS channel.
if (authority_state.xds_channel != xds_channel()) continue;
if (authority_state.xds_channels.back() != xds_channel()) {
continue;
}
auto seen_authority_it = result.resources_seen.find(authority);
// Find this resource type.
auto type_it = authority_state.resource_map.find(result.type);
@ -1567,6 +1640,18 @@ RefCountedPtr<XdsClient::XdsChannel> XdsClient::GetOrCreateXdsChannelLocked(
return xds_channel;
}
bool XdsClient::HasUncachedResources(const AuthorityState& authority_state) {
for (const auto& type_resource : authority_state.resource_map) {
for (const auto& key_state : type_resource.second) {
if (key_state.second.meta.client_status ==
XdsApi::ResourceMetadata::REQUESTED) {
return true;
}
}
}
return false;
}
void XdsClient::WatchResource(const XdsResourceType* type,
absl::string_view name,
RefCountedPtr<ResourceWatcherInterface> watcher) {
@ -1592,7 +1677,7 @@ void XdsClient::WatchResource(const XdsResourceType* type,
return;
}
// Find server to use.
const XdsBootstrap::XdsServer* xds_server = nullptr;
std::vector<const XdsBootstrap::XdsServer*> xds_servers;
if (resource_name->authority != kOldStyleAuthority) {
auto* authority =
bootstrap_->LookupAuthority(std::string(resource_name->authority));
@ -1602,75 +1687,100 @@ void XdsClient::WatchResource(const XdsResourceType* type,
"\" not present in bootstrap config")));
return;
}
xds_server =
authority->servers().empty() ? nullptr : authority->servers().front();
xds_servers = authority->servers();
}
if (xds_server == nullptr) xds_server = bootstrap_->servers().front();
if (xds_servers.empty()) xds_servers = bootstrap_->servers();
{
MutexLock lock(&mu_);
MaybeRegisterResourceTypeLocked(type);
AuthorityState& authority_state =
authority_state_map_[resource_name->authority];
ResourceState& resource_state =
authority_state.resource_map[type][resource_name->key];
auto it_is_new = authority_state.resource_map[type].emplace(
resource_name->key, ResourceState());
bool first_watcher_for_resource = it_is_new.second;
ResourceState& resource_state = it_is_new.first->second;
resource_state.watchers[w] = watcher;
// If we already have a cached value for the resource, notify the new
// watcher immediately.
if (resource_state.resource != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
"[xds_client %p] returning cached listener data for %s", this,
std::string(name).c_str());
}
work_serializer_.Schedule(
[watcher, value = resource_state.resource]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
watcher->OnGenericResourceChanged(value,
ReadDelayHandle::NoWait());
},
DEBUG_LOCATION);
} else if (resource_state.meta.client_status ==
XdsApi::ResourceMetadata::DOES_NOT_EXIST) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
"[xds_client %p] reporting cached does-not-exist for %s", this,
std::string(name).c_str());
if (first_watcher_for_resource) {
// We try to add new channels in 2 cases:
// - This is the first resource for this authority (i.e., the list
// of channels is empty).
// - The last channel in the list is failing. That failure may not
// have previously triggered fallback if there were no uncached
// resources, but we've just added a new uncached resource,
// so we need to trigger fallback now.
//
// Note that when we add a channel, it might already be failing
// due to being used in a different authority. So we keep going
// until either we add one that isn't failing or we've added them all.
if (authority_state.xds_channels.empty() ||
!authority_state.xds_channels.back()->status().ok()) {
for (size_t i = authority_state.xds_channels.size();
i < xds_servers.size(); ++i) {
authority_state.xds_channels.emplace_back(
GetOrCreateXdsChannelLocked(*xds_servers[i], "start watch"));
if (authority_state.xds_channels.back()->status().ok()) {
break;
}
}
}
work_serializer_.Schedule(
[watcher]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
watcher->OnResourceDoesNotExist(ReadDelayHandle::NoWait());
},
DEBUG_LOCATION);
} else if (resource_state.meta.client_status ==
XdsApi::ResourceMetadata::NACKED) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(
GPR_INFO,
"[xds_client %p] reporting cached validation failure for %s: %s",
this, std::string(name).c_str(),
resource_state.meta.failed_details.c_str());
for (const auto& channel : authority_state.xds_channels) {
channel->SubscribeLocked(type, *resource_name);
}
std::string details = resource_state.meta.failed_details;
const auto* node = bootstrap_->node();
if (node != nullptr) {
absl::StrAppend(&details, " (node ID:", bootstrap_->node()->id(), ")");
} else {
// If we already have a cached value for the resource, notify the new
// watcher immediately.
if (resource_state.resource != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
"[xds_client %p] returning cached listener data for %s", this,
std::string(name).c_str());
}
work_serializer_.Schedule(
[watcher, value = resource_state.resource]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
watcher->OnGenericResourceChanged(value,
ReadDelayHandle::NoWait());
},
DEBUG_LOCATION);
} else if (resource_state.meta.client_status ==
XdsApi::ResourceMetadata::DOES_NOT_EXIST) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
"[xds_client %p] reporting cached does-not-exist for %s",
this, std::string(name).c_str());
}
work_serializer_.Schedule(
[watcher]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
watcher->OnResourceDoesNotExist(ReadDelayHandle::NoWait());
},
DEBUG_LOCATION);
} else if (resource_state.meta.client_status ==
XdsApi::ResourceMetadata::NACKED) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(
GPR_INFO,
"[xds_client %p] reporting cached validation failure for %s: %s",
this, std::string(name).c_str(),
resource_state.meta.failed_details.c_str());
}
std::string details = resource_state.meta.failed_details;
const auto* node = bootstrap_->node();
if (node != nullptr) {
absl::StrAppend(&details, " (node ID:", bootstrap_->node()->id(),
")");
}
work_serializer_.Schedule(
[watcher, details = std::move(details)]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
watcher->OnError(absl::UnavailableError(absl::StrCat(
"invalid resource: ", details)),
ReadDelayHandle::NoWait());
},
DEBUG_LOCATION);
}
work_serializer_.Schedule(
[watcher, details = std::move(details)]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
watcher->OnError(absl::UnavailableError(absl::StrCat(
"invalid resource: ", details)),
ReadDelayHandle::NoWait());
},
DEBUG_LOCATION);
}
// If the authority doesn't yet have a channel, set it, creating it if
// needed.
if (authority_state.xds_channel == nullptr) {
authority_state.xds_channel =
GetOrCreateXdsChannelLocked(*xds_server, "start watch");
}
absl::Status channel_status = authority_state.xds_channel->status();
absl::Status channel_status = authority_state.xds_channels.back()->status();
if (!channel_status.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO,
@ -1685,7 +1795,6 @@ void XdsClient::WatchResource(const XdsResourceType* type,
},
DEBUG_LOCATION);
}
authority_state.xds_channel->SubscribeLocked(type, *resource_name);
}
work_serializer_.DrainQueue();
}
@ -1723,13 +1832,15 @@ void XdsClient::CancelResourceWatch(const XdsResourceType* type,
this, std::string(type->type_url()).c_str(),
std::string(name).c_str());
}
authority_state.xds_channel->UnsubscribeLocked(type, *resource_name,
delay_unsubscription);
for (const auto& xds_channel : authority_state.xds_channels) {
xds_channel->UnsubscribeLocked(type, *resource_name,
delay_unsubscription);
}
type_map.erase(resource_it);
if (type_map.empty()) {
authority_state.resource_map.erase(type_it);
if (authority_state.resource_map.empty()) {
authority_state.xds_channel.reset();
authority_state.xds_channels.clear();
}
}
}

@ -201,6 +201,8 @@ class XdsClient : public DualRefCounted<XdsClient> {
}
};
struct AuthorityState;
struct XdsResourceName {
std::string authority;
XdsResourceKey key;
@ -244,6 +246,12 @@ class XdsClient : public DualRefCounted<XdsClient> {
absl::string_view server_uri() const { return server_.server_uri(); }
private:
// Attempts to find a suitable Xds fallback server. Returns true if
// a connection to a suitable server had been established.
bool MaybeFallbackLocked(const std::string& authority,
XdsClient::AuthorityState& authority_state)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
void SetHealthyLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
void Orphaned() override;
void OnConnectivityFailure(absl::Status status);
@ -283,7 +291,7 @@ class XdsClient : public DualRefCounted<XdsClient> {
};
struct AuthorityState {
RefCountedPtr<XdsChannel> xds_channel;
std::vector<RefCountedPtr<XdsChannel>> xds_channels;
std::map<const XdsResourceType*, std::map<XdsResourceKey, ResourceState>>
resource_map;
};
@ -339,10 +347,10 @@ class XdsClient : public DualRefCounted<XdsClient> {
XdsApi::ClusterLoadReportMap BuildLoadReportSnapshotLocked(
const XdsBootstrap::XdsServer& xds_server, bool send_all_clusters,
const std::set<std::string>& clusters) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
RefCountedPtr<XdsChannel> GetOrCreateXdsChannelLocked(
const XdsBootstrap::XdsServer& server, const char* reason)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
bool HasUncachedResources(const AuthorityState& authority_state);
std::unique_ptr<XdsBootstrap> bootstrap_;
OrphanablePtr<XdsTransportFactory> transport_factory_;

@ -257,8 +257,8 @@ absl::StatusOr<RefCountedPtr<GrpcXdsClient>> GrpcXdsClient::GetOrCreate(
MakeOrphanable<GrpcXdsTransportFactory>(channel_args));
g_xds_client_map->emplace(xds_client->key(), xds_client.get());
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO, "xDS client for key: %s was created",
std::string(key).c_str());
gpr_log(GPR_INFO, "[xds_client %p] Created xDS client for key %s",
xds_client.get(), std::string(key).c_str());
}
return xds_client;
}

@ -175,6 +175,14 @@ class ValueOrFailure {
return value_ == other.value_;
}
bool operator!=(const ValueOrFailure& other) const {
return value_ != other.value_;
}
bool operator==(const T& other) const { return value_ == other; }
bool operator!=(const T& other) const { return value_ != other; }
private:
absl::optional<T> value_;
};

@ -202,15 +202,53 @@ void CallFilters::Finalize(const grpc_call_final_info* final_info) {
}
}
void CallFilters::CancelDueToFailedPipeOperation() {
void CallFilters::CancelDueToFailedPipeOperation(SourceLocation but_where) {
// We expect something cancelled before now
if (server_trailing_metadata_ == nullptr) return;
gpr_log(GPR_DEBUG, "Cancelling due to failed pipe operation");
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_promise_primitives)) {
gpr_log(but_where.file(), but_where.line(), GPR_LOG_SEVERITY_DEBUG,
"Cancelling due to failed pipe operation: %s",
DebugString().c_str());
}
server_trailing_metadata_ =
ServerMetadataFromStatus(absl::CancelledError("Failed pipe operation"));
server_trailing_metadata_waiter_.Wake();
}
void CallFilters::PushServerTrailingMetadata(ServerMetadataHandle md) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_promise_primitives)) {
gpr_log(GPR_DEBUG, "%s Push server trailing metadata: %s into %s",
GetContext<Activity>()->DebugTag().c_str(),
md->DebugString().c_str(), DebugString().c_str());
}
GPR_ASSERT(md != nullptr);
if (server_trailing_metadata_ != nullptr) return;
server_trailing_metadata_ = std::move(md);
client_initial_metadata_state_.CloseWithError();
server_initial_metadata_state_.CloseSending();
client_to_server_message_state_.CloseWithError();
server_to_client_message_state_.CloseWithError();
server_trailing_metadata_waiter_.Wake();
}
std::string CallFilters::DebugString() const {
std::vector<std::string> components = {
absl::StrFormat("this:%p", this),
absl::StrCat("client_initial_metadata:",
client_initial_metadata_state_.DebugString()),
ServerInitialMetadataPromises::DebugString("server_initial_metadata",
this),
ClientToServerMessagePromises::DebugString("client_to_server_message",
this),
ServerToClientMessagePromises::DebugString("server_to_client_message",
this),
absl::StrCat("server_trailing_metadata:",
server_trailing_metadata_ == nullptr
? "not-set"
: server_trailing_metadata_->DebugString())};
return absl::StrCat("CallFilters{", absl::StrJoin(components, ", "), "}");
};
///////////////////////////////////////////////////////////////////////////////
// CallFilters::Stack
@ -251,6 +289,49 @@ void filters_detail::PipeState::Start() {
wait_recv_.Wake();
}
void filters_detail::PipeState::CloseWithError() {
if (state_ == ValueState::kClosed) return;
state_ = ValueState::kError;
wait_recv_.Wake();
wait_send_.Wake();
}
Poll<bool> filters_detail::PipeState::PollClosed() {
switch (state_) {
case ValueState::kIdle:
case ValueState::kWaiting:
case ValueState::kQueued:
case ValueState::kReady:
case ValueState::kProcessing:
return wait_recv_.pending();
case ValueState::kClosed:
return false;
case ValueState::kError:
return true;
}
GPR_UNREACHABLE_CODE(return Pending{});
}
void filters_detail::PipeState::CloseSending() {
switch (state_) {
case ValueState::kIdle:
state_ = ValueState::kClosed;
break;
case ValueState::kWaiting:
state_ = ValueState::kClosed;
wait_recv_.Wake();
break;
case ValueState::kClosed:
case ValueState::kError:
break;
case ValueState::kQueued:
case ValueState::kReady:
case ValueState::kProcessing:
Crash("Only one push allowed to be outstanding");
break;
}
}
void filters_detail::PipeState::BeginPush() {
switch (state_) {
case ValueState::kIdle:
@ -320,7 +401,7 @@ Poll<StatusFlag> filters_detail::PipeState::PollPush() {
GPR_UNREACHABLE_CODE(return Pending{});
}
Poll<StatusFlag> filters_detail::PipeState::PollPull() {
Poll<ValueOrFailure<bool>> filters_detail::PipeState::PollPull() {
switch (state_) {
case ValueState::kWaiting:
return wait_recv_.pending();
@ -331,10 +412,11 @@ Poll<StatusFlag> filters_detail::PipeState::PollPull() {
case ValueState::kQueued:
if (!started_) return wait_recv_.pending();
state_ = ValueState::kProcessing;
return Success{};
return true;
case ValueState::kProcessing:
Crash("Only one pull allowed to be outstanding");
case ValueState::kClosed:
return false;
case ValueState::kError:
return Failure{};
}
@ -358,4 +440,32 @@ void filters_detail::PipeState::AckPull() {
}
}
std::string filters_detail::PipeState::DebugString() const {
const char* state_str = "<<invalid-value>>";
switch (state_) {
case ValueState::kIdle:
state_str = "Idle";
break;
case ValueState::kWaiting:
state_str = "Waiting";
break;
case ValueState::kQueued:
state_str = "Queued";
break;
case ValueState::kReady:
state_str = "Ready";
break;
case ValueState::kProcessing:
state_str = "Processing";
break;
case ValueState::kClosed:
state_str = "Closed";
break;
case ValueState::kError:
state_str = "Error";
break;
}
return absl::StrCat(state_str, started_ ? "" : " (not started)");
}
} // namespace grpc_core

@ -23,6 +23,8 @@
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/promise/latch.h"
#include "src/core/lib/promise/map.h"
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/status_flag.h"
#include "src/core/lib/transport/call_final_info.h"
@ -771,6 +773,55 @@ struct AddOpImpl<
}
};
// PROMISE_RETURNING(absl::StatusOr<$VALUE_HANDLE>)
// $INTERCEPTOR_NAME($VALUE_HANDLE, FilterType*)
template <typename FilterType, typename T, typename R,
R (FilterType::Call::*impl)(T, FilterType*)>
struct AddOpImpl<FilterType, T, R (FilterType::Call::*)(T, FilterType*), impl,
absl::enable_if_t<std::is_same<absl::StatusOr<T>,
PromiseResult<R>>::value>> {
static void Add(FilterType* channel_data, size_t call_offset,
Layout<FallibleOperator<T>>& to) {
class Promise {
public:
Promise(T value, typename FilterType::Call* call_data,
FilterType* channel_data)
: impl_((call_data->*impl)(std::move(value), channel_data)) {}
Poll<ResultOr<T>> PollOnce() {
auto p = impl_();
auto* r = p.value_if_ready();
if (r == nullptr) return Pending{};
this->~Promise();
if (r->ok()) return ResultOr<T>{std::move(**r), nullptr};
return ResultOr<T>{nullptr, ServerMetadataFromStatus(r->status())};
}
private:
GPR_NO_UNIQUE_ADDRESS R impl_;
};
to.Add(sizeof(Promise), alignof(Promise),
FallibleOperator<T>{
channel_data,
call_offset,
[](void* promise_data, void* call_data, void* channel_data,
T value) -> Poll<ResultOr<T>> {
auto* promise = new (promise_data)
Promise(std::move(value),
static_cast<typename FilterType::Call*>(call_data),
static_cast<FilterType*>(channel_data));
return promise->PollOnce();
},
[](void* promise_data) {
return static_cast<Promise*>(promise_data)->PollOnce();
},
[](void* promise_data) {
static_cast<Promise*>(promise_data)->~Promise();
},
});
}
};
struct ChannelDataDestructor {
void (*destroy)(void* channel_data);
void* channel_data;
@ -783,7 +834,7 @@ struct ChannelDataDestructor {
// in-flight calls.
struct StackData {
// Overall size and alignment of the call data for this stack.
size_t call_data_alignment = 0;
size_t call_data_alignment = 1;
size_t call_data_size = 0;
// A complete list of filters for this call, so that we can construct the
// call data for each filter.
@ -1104,14 +1155,25 @@ class PipeState {
void DropPush();
// Poll for push completion: occurs after the corresponding Pull()
Poll<StatusFlag> PollPush();
Poll<StatusFlag> PollPull();
// Poll for pull completion; returns Failure{} if closed with error,
// true if a value is available, or false if the pipe was closed without
// error.
Poll<ValueOrFailure<bool>> PollPull();
// A pulled value has been consumed: we can unblock the push
void AckPull();
// A previously started pull operation has completed
void DropPull();
// Close sending
void CloseSending();
// Close sending with error
void CloseWithError();
// Poll for closedness - if true, closed with error
Poll<bool> PollClosed();
bool holds_error() const { return state_ == ValueState::kError; }
std::string DebugString() const;
private:
enum class ValueState : uint8_t {
// Nothing sending nor receiving
@ -1248,6 +1310,44 @@ class CallFilters {
filters_detail::StackData data_;
};
class NextMessage {
public:
NextMessage() : has_value_(false), cancelled_(false) {}
explicit NextMessage(MessageHandle value)
: has_value_(true), value_(std::move(value)) {}
explicit NextMessage(bool cancelled)
: has_value_(false), cancelled_(cancelled) {}
NextMessage(const NextMessage&) = delete;
NextMessage& operator=(const NextMessage&) = delete;
NextMessage(NextMessage&& other) noexcept = default;
NextMessage& operator=(NextMessage&& other) = default;
using value_type = MessageHandle;
void reset() {
has_value_ = false;
cancelled_ = false;
value_.reset();
}
bool has_value() const { return has_value_; }
const MessageHandle& value() const {
GPR_DEBUG_ASSERT(has_value_);
return value_;
}
MessageHandle& value() {
GPR_DEBUG_ASSERT(has_value_);
return value_;
}
const MessageHandle& operator*() const { return value(); }
MessageHandle& operator*() { return value(); }
bool cancelled() const { return !has_value_ && cancelled_; }
private:
bool has_value_;
bool cancelled_;
MessageHandle value_;
};
explicit CallFilters(ClientMetadataHandle client_initial_metadata);
~CallFilters();
@ -1258,25 +1358,59 @@ class CallFilters {
void SetStack(RefCountedPtr<Stack> stack);
// Access client initial metadata before it's processed
ClientMetadata* unprocessed_client_initial_metadata() {
return client_initial_metadata_.get();
}
// Client: Fetch client initial metadata
// Returns a promise that resolves to ValueOrFailure<ClientMetadataHandle>
GRPC_MUST_USE_RESULT auto PullClientInitialMetadata();
// Server: Indicate that no server initial metadata will be sent
void NoServerInitialMetadata() {
server_initial_metadata_state_.CloseSending();
}
// Server: Push server initial metadata
// Returns a promise that resolves to a StatusFlag indicating success
GRPC_MUST_USE_RESULT auto PushServerInitialMetadata(ServerMetadataHandle md);
// Client: Fetch server initial metadata
// Returns a promise that resolves to ValueOrFailure<ServerMetadataHandle>
GRPC_MUST_USE_RESULT auto PullServerInitialMetadata();
// Client: Push client to server message
// Returns a promise that resolves to a StatusFlag indicating success
GRPC_MUST_USE_RESULT auto PushClientToServerMessage(MessageHandle message);
// Client: Indicate that no more messages will be sent
void FinishClientToServerSends() {
client_to_server_message_state_.CloseSending();
}
// Server: Fetch client to server message
// Returns a promise that resolves to ValueOrFailure<MessageHandle>
GRPC_MUST_USE_RESULT auto PullClientToServerMessage();
// Server: Push server to client message
// Returns a promise that resolves to a StatusFlag indicating success
GRPC_MUST_USE_RESULT auto PushServerToClientMessage(MessageHandle message);
// Server: Fetch server to client message
// Returns a promise that resolves to ValueOrFailure<MessageHandle>
GRPC_MUST_USE_RESULT auto PullServerToClientMessage();
void PushServerTrailingMetadata(ServerMetadataHandle md) {
GPR_ASSERT(md != nullptr);
if (server_trailing_metadata_ != nullptr) return;
server_trailing_metadata_ = std::move(md);
server_trailing_metadata_waiter_.Wake();
}
// Server: Indicate end of response
// Closes the request entirely - no messages can be sent/received
// If no server initial metadata has been sent, implies
// NoServerInitialMetadata() called.
void PushServerTrailingMetadata(ServerMetadataHandle md);
// Client: Fetch server trailing metadata
// Returns a promise that resolves to ServerMetadataHandle
GRPC_MUST_USE_RESULT auto PullServerTrailingMetadata();
// Server: Wait for server trailing metadata to have been sent
// Returns a promise that resolves to a StatusFlag indicating whether the
// request was cancelled or not -- failure to send trailing metadata is
// considered a cancellation, as is actual cancellation -- but not application
// errors.
GRPC_MUST_USE_RESULT auto WasCancelled();
// Client & server: fill in final_info with the final status of the call.
void Finalize(const grpc_call_final_info* final_info);
std::string DebugString() const;
private:
template <filters_detail::PipeState(CallFilters::*state_ptr),
void*(CallFilters::*push_ptr), typename T,
@ -1315,6 +1449,10 @@ class CallFilters {
T TakeValue() { return std::move(value_); }
absl::string_view DebugString() const {
return value_ != nullptr ? " (not pulled)" : "";
}
private:
filters_detail::PipeState& state() { return filters_->*state_ptr; }
void*& push_slot() { return filters_->*push_ptr; }
@ -1323,24 +1461,36 @@ class CallFilters {
T value_;
};
class Pull {
static std::string DebugString(absl::string_view name,
const CallFilters* filters) {
auto* push = static_cast<Push*>(filters->*push_ptr);
return absl::StrCat(name, ":", (filters->*state_ptr).DebugString(),
push == nullptr ? "" : push->DebugString());
}
class PullMaybe {
public:
explicit Pull(CallFilters* filters) : filters_(filters) {}
~Pull() {
explicit PullMaybe(CallFilters* filters) : filters_(filters) {}
~PullMaybe() {
if (filters_ != nullptr) {
state().DropPull();
}
}
Pull(const Pull&) = delete;
Pull& operator=(const Pull&) = delete;
Pull(Pull&& other) noexcept
PullMaybe(const PullMaybe&) = delete;
PullMaybe& operator=(const PullMaybe&) = delete;
PullMaybe(PullMaybe&& other) noexcept
: filters_(std::exchange(other.filters_, nullptr)),
executor_(std::move(other.executor_)) {}
Pull& operator=(Pull&&) = delete;
PullMaybe& operator=(PullMaybe&&) = delete;
Poll<ValueOrFailure<T>> operator()() {
Poll<ValueOrFailure<absl::optional<T>>> operator()() {
if (executor_.IsRunning()) {
auto c = state().PollClosed();
if (c.ready() && c.value()) {
filters_->CancelDueToFailedPipeOperation();
return Failure{};
}
return FinishOperationExecutor(executor_.Step(filters_->call_data_));
}
auto p = state().PollPull();
@ -1350,6 +1500,7 @@ class CallFilters {
filters_->CancelDueToFailedPipeOperation();
return Failure{};
}
if (!**r) return absl::nullopt;
return FinishOperationExecutor(executor_.Start(
layout(), push()->TakeValue(), filters_->call_data_));
}
@ -1362,7 +1513,7 @@ class CallFilters {
return &(filters_->stack_->data_.*layout_ptr);
}
Poll<ValueOrFailure<T>> FinishOperationExecutor(
Poll<ValueOrFailure<absl::optional<T>>> FinishOperationExecutor(
Poll<filters_detail::ResultOr<T>> p) {
auto* r = p.value_if_ready();
if (r == nullptr) return Pending{};
@ -1376,6 +1527,66 @@ class CallFilters {
CallFilters* filters_;
filters_detail::OperationExecutor<T> executor_;
};
class PullMessage {
public:
explicit PullMessage(CallFilters* filters) : filters_(filters) {}
~PullMessage() {
if (filters_ != nullptr) {
state().DropPull();
}
}
PullMessage(const PullMessage&) = delete;
PullMessage& operator=(const PullMessage&) = delete;
PullMessage(PullMessage&& other) noexcept
: filters_(std::exchange(other.filters_, nullptr)),
executor_(std::move(other.executor_)) {}
PullMessage& operator=(PullMessage&&) = delete;
Poll<NextMessage> operator()() {
if (executor_.IsRunning()) {
auto c = state().PollClosed();
if (c.ready() && c.value()) {
filters_->CancelDueToFailedPipeOperation();
return NextMessage(true);
}
return FinishOperationExecutor(executor_.Step(filters_->call_data_));
}
auto p = state().PollPull();
auto* r = p.value_if_ready();
if (r == nullptr) return Pending{};
if (!r->ok()) {
filters_->CancelDueToFailedPipeOperation();
return NextMessage(true);
}
if (!**r) return NextMessage(false);
return FinishOperationExecutor(executor_.Start(
layout(), push()->TakeValue(), filters_->call_data_));
}
private:
filters_detail::PipeState& state() { return filters_->*state_ptr; }
Push* push() { return static_cast<Push*>(filters_->*push_ptr); }
const filters_detail::Layout<filters_detail::FallibleOperator<T>>*
layout() {
return &(filters_->stack_->data_.*layout_ptr);
}
Poll<NextMessage> FinishOperationExecutor(
Poll<filters_detail::ResultOr<T>> p) {
auto* r = p.value_if_ready();
if (r == nullptr) return Pending{};
GPR_DEBUG_ASSERT(!executor_.IsRunning());
state().AckPull();
if (r->ok != nullptr) return NextMessage(std::move(r->ok));
filters_->PushServerTrailingMetadata(std::move(r->error));
return NextMessage(true);
}
CallFilters* filters_;
filters_detail::OperationExecutor<T> executor_;
};
};
class PullClientInitialMetadataPromise {
@ -1400,7 +1611,12 @@ class CallFilters {
}
auto p = state().PollPull();
auto* r = p.value_if_ready();
gpr_log(GPR_INFO, "%s", r == nullptr ? "PENDING" : r->ToString().c_str());
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_promise_primitives)) {
gpr_log(GPR_INFO, "%s",
r == nullptr
? "PENDING"
: (r->ok() ? (r->value() ? "TRUE" : "FALSE") : "FAILURE"));
}
if (r == nullptr) return Pending{};
if (!r->ok()) {
filters_->CancelDueToFailedPipeOperation();
@ -1450,11 +1666,39 @@ class CallFilters {
Poll<ServerMetadataHandle> operator()() {
if (executor_.IsRunning()) {
return executor_.Step(filters_->call_data_);
auto r = executor_.Step(filters_->call_data_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_promise_primitives)) {
if (r.pending()) {
gpr_log(GPR_INFO,
"%s PullServerTrailingMetadata[%p]: Pending(but executing)",
GetContext<Activity>()->DebugTag().c_str(), filters_);
} else {
gpr_log(GPR_INFO, "%s PullServerTrailingMetadata[%p]: Ready: %s",
GetContext<Activity>()->DebugTag().c_str(), filters_,
r.value()->DebugString().c_str());
}
}
return r;
}
if (filters_->server_trailing_metadata_ == nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_promise_primitives)) {
gpr_log(GPR_INFO,
"%s PullServerTrailingMetadata[%p]: Pending(not pushed)",
GetContext<Activity>()->DebugTag().c_str(), filters_);
}
return filters_->server_trailing_metadata_waiter_.pending();
}
// If no stack has been set, we can just return the result of the call
if (filters_->stack_ == nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_promise_primitives)) {
gpr_log(GPR_INFO,
"%s PullServerTrailingMetadata[%p]: Ready(no-stack): %s",
GetContext<Activity>()->DebugTag().c_str(), filters_,
filters_->server_trailing_metadata_->DebugString().c_str());
}
return std::move(filters_->server_trailing_metadata_);
}
// Otherwise we need to process it through all the filters.
return executor_.Start(&filters_->stack_->data_.server_trailing_metadata,
std::move(filters_->server_trailing_metadata_),
filters_->call_data_);
@ -1465,7 +1709,7 @@ class CallFilters {
filters_detail::InfallibleOperationExecutor<ServerMetadataHandle> executor_;
};
void CancelDueToFailedPipeOperation();
void CancelDueToFailedPipeOperation(SourceLocation but_where = {});
RefCountedPtr<Stack> stack_;
@ -1475,6 +1719,7 @@ class CallFilters {
filters_detail::PipeState client_to_server_message_state_;
filters_detail::PipeState server_to_client_message_state_;
IntraActivityWaiter server_trailing_metadata_waiter_;
Latch<bool> cancelled_;
void* call_data_;
ClientMetadataHandle client_initial_metadata_;
@ -1516,7 +1761,7 @@ inline auto CallFilters::PushServerInitialMetadata(ServerMetadataHandle md) {
}
inline auto CallFilters::PullServerInitialMetadata() {
return ServerInitialMetadataPromises::Pull{this};
return ServerInitialMetadataPromises::PullMaybe{this};
}
inline auto CallFilters::PushClientToServerMessage(MessageHandle message) {
@ -1526,7 +1771,7 @@ inline auto CallFilters::PushClientToServerMessage(MessageHandle message) {
}
inline auto CallFilters::PullClientToServerMessage() {
return ClientToServerMessagePromises::Pull{this};
return ClientToServerMessagePromises::PullMessage{this};
}
inline auto CallFilters::PushServerToClientMessage(MessageHandle message) {
@ -1536,13 +1781,19 @@ inline auto CallFilters::PushServerToClientMessage(MessageHandle message) {
}
inline auto CallFilters::PullServerToClientMessage() {
return ServerToClientMessagePromises::Pull{this};
return ServerToClientMessagePromises::PullMessage{this};
}
inline auto CallFilters::PullServerTrailingMetadata() {
return PullServerTrailingMetadataPromise(this);
return Map(PullServerTrailingMetadataPromise(this),
[this](ServerMetadataHandle h) {
cancelled_.Set(h->get(GrpcCallWasCancelled()).value_or(false));
return h;
});
}
inline auto CallFilters::WasCancelled() { return cancelled_.Wait(); }
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_FILTERS_H

@ -437,8 +437,9 @@ cdef class ComputeEngineChannelCredentials(ChannelCredentials):
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
with nogil:
self._c_creds = grpc_google_default_credentials_create(self._call_creds)
return self._c_creds
def channel_credentials_compute_engine(call_creds):

@ -112,20 +112,61 @@ class ChannelConnectivityTest(unittest.TestCase):
class ChannelTest(unittest.TestCase):
def test_secure_channel(self):
channel_credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel("google.com:443", channel_credentials)
def compute_engine_channel_credentials(self):
class TestCallCredentials(grpc.AuthMetadataPlugin):
def __call__(self, context, callback):
callback((), None)
test_call_credentials = TestCallCredentials()
call_credentials = grpc.metadata_call_credentials(
test_call_credentials, "test call credentials"
)
return grpc.compute_engine_channel_credentials(call_credentials)
def test_ssl_secure_channel(self):
channel = grpc.secure_channel(
"google.com:443", grpc.ssl_channel_credentials()
)
channel.close()
def test_compute_engine_secure_channel(self):
channel = grpc.secure_channel(
"google.com:443", self.compute_engine_channel_credentials()
)
channel.close()
def test_multiple_secure_channel(self):
def test_multiple_ssl_secure_channel(self):
_THREAD_COUNT = 10
wait_group = test_common.WaitGroup(_THREAD_COUNT)
def create_secure_channel():
wait_group.done()
wait_group.wait()
channel = grpc.secure_channel(
"google.com:443", grpc.ssl_channel_credentials()
)
channel.close()
threads = []
for _ in range(_THREAD_COUNT):
thread = threading.Thread(target=create_secure_channel)
thread.setDaemon(True)
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
def test_multiple_compute_engine_secure_channel(self):
_THREAD_COUNT = 10
wait_group = test_common.WaitGroup(_THREAD_COUNT)
def create_secure_channel():
channel_credentials = grpc.ssl_channel_credentials()
wait_group.done()
wait_group.wait()
channel = grpc.secure_channel("google.com:443", channel_credentials)
channel = grpc.secure_channel(
"google.com:443", self.compute_engine_channel_credentials()
)
channel.close()
threads = []

@ -14,8 +14,6 @@
// limitations under the License.
//
#include <grpc/support/port_platform.h>
#include "src/core/lib/address_utils/sockaddr_utils.h"
#include <errno.h>
@ -27,6 +25,8 @@
#include "absl/strings/str_cat.h"
#include "gtest/gtest.h"
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/resolved_address.h"
#ifdef GRPC_HAVE_UNIX_SOCKET

@ -14,14 +14,13 @@
// limitations under the License.
//
#include <grpc/support/port_platform.h>
#include <memory>
#include "absl/types/optional.h"
#include "gtest/gtest.h"
#include <grpc/impl/channel_arg_names.h>
#include <grpc/support/port_platform.h>
#include "src/core/client_channel/client_channel_filter.h"
#include "src/core/client_channel/subchannel_pool_interface.h"

@ -17,8 +17,6 @@
#ifndef GRPC_TEST_CORE_CLIENT_CHANNEL_LB_POLICY_LB_POLICY_TEST_LIB_H
#define GRPC_TEST_CORE_CLIENT_CHANNEL_LB_POLICY_LB_POLICY_TEST_LIB_H
#include <grpc/support/port_platform.h>
#include <inttypes.h>
#include <stddef.h>
@ -53,6 +51,7 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include "src/core/client_channel/client_channel_internal.h"
#include "src/core/client_channel/subchannel_interface_internal.h"

@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "gtest/gtest.h"
#include <grpc/support/port_platform.h>
// Make a template argument to test which bit pattern remains in A's destructor
// to try and detect similar bugs in non-MSAN builds (none have been detected
// yet thankfully)

@ -256,12 +256,14 @@ grpc_cc_library(
srcs = [
"end2end_test_fuzzer.cc",
],
hdrs = [
"end2end_test_fuzzer.h",
],
external_deps = [
"absl/functional:any_invocable",
"absl/strings",
"absl/types:optional",
"gtest",
"libprotobuf_mutator",
],
tags = ["nofixdeps"],
deps = [

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/core/end2end/end2end_test_fuzzer.h"
#include <stdio.h>
#include <algorithm>
@ -24,11 +26,6 @@
#include <gtest/gtest.h>
#include "absl/functional/any_invocable.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/log.h>
@ -39,8 +36,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/timer_manager.h"
#include "src/libfuzzer/libfuzzer_macro.h"
#include "test/core/end2end/end2end_test_fuzzer.pb.h"
#include "test/core/end2end/end2end_tests.h"
#include "test/core/end2end/fixtures/h2_tls_common.h"
#include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h"
@ -53,23 +48,23 @@ using ::grpc_event_engine::experimental::GetDefaultEventEngine;
bool squelch = true;
static void dont_log(gpr_log_func_args* /*args*/) {}
DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) {
namespace grpc_core {
void RunEnd2endFuzzer(const core_end2end_test_fuzzer::Msg& msg) {
struct Test {
std::string name;
absl::AnyInvocable<std::unique_ptr<grpc_core::CoreEnd2endTest>() const>
factory;
absl::AnyInvocable<std::unique_ptr<CoreEnd2endTest>() const> factory;
};
static const auto only_suite = grpc_core::GetEnv("GRPC_TEST_FUZZER_SUITE");
static const auto only_test = grpc_core::GetEnv("GRPC_TEST_FUZZER_TEST");
static const auto only_config = grpc_core::GetEnv("GRPC_TEST_FUZZER_CONFIG");
static const auto only_suite = GetEnv("GRPC_TEST_FUZZER_SUITE");
static const auto only_test = GetEnv("GRPC_TEST_FUZZER_TEST");
static const auto only_config = GetEnv("GRPC_TEST_FUZZER_CONFIG");
static const auto all_tests =
grpc_core::CoreEnd2endTestRegistry::Get().AllTests();
static const auto all_tests = CoreEnd2endTestRegistry::Get().AllTests();
static const auto tests = []() {
grpc_core::g_is_fuzzing_core_e2e_tests = true;
grpc_core::ForceEnableExperiment("event_engine_client", true);
grpc_core::ForceEnableExperiment("event_engine_listener", true);
g_is_fuzzing_core_e2e_tests = true;
ForceEnableExperiment("event_engine_client", true);
ForceEnableExperiment("event_engine_listener", true);
std::vector<Test> tests;
for (const auto& test : all_tests) {
@ -81,11 +76,10 @@ DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) {
}
std::string test_name =
absl::StrCat(test.suite, ".", test.name, "/", test.config->name);
tests.emplace_back(
Test{std::move(test_name), [&test]() {
return std::unique_ptr<grpc_core::CoreEnd2endTest>(
test.make_test(test.config));
}});
tests.emplace_back(Test{std::move(test_name), [&test]() {
return std::unique_ptr<CoreEnd2endTest>(
test.make_test(test.config));
}});
}
std::sort(tests.begin(), tests.end(),
[](const Test& a, const Test& b) { return a.name < b.name; });
@ -95,16 +89,16 @@ DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) {
const int test_id = msg.test_id() % tests.size();
if (squelch && !grpc_core::GetEnv("GRPC_TRACE_FUZZER").has_value()) {
if (squelch && !GetEnv("GRPC_TRACE_FUZZER").has_value()) {
gpr_set_log_function(dont_log);
}
// TODO(ctiller): make this per fixture?
grpc_core::ConfigVars::Overrides overrides =
grpc_core::OverridesFromFuzzConfigVars(msg.config_vars());
ConfigVars::Overrides overrides =
OverridesFromFuzzConfigVars(msg.config_vars());
overrides.default_ssl_roots_file_path = CA_CERT_PATH;
grpc_core::ConfigVars::SetOverrides(overrides);
grpc_core::TestOnlyReloadExperimentsFromConfigVariables();
ConfigVars::SetOverrides(overrides);
TestOnlyReloadExperimentsFromConfigVariables();
grpc_event_engine::experimental::SetEventEngineFactory(
[actions = msg.event_engine_actions()]() {
FuzzingEventEngine::Options options;
@ -126,18 +120,20 @@ DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) {
test->SetCqVerifierStepFn(
[engine = std::move(engine)](
grpc_event_engine::experimental::EventEngine::Duration max_step) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
ApplicationCallbackExecCtx callback_exec_ctx;
ExecCtx exec_ctx;
engine->Tick(max_step);
grpc_timer_manager_tick();
});
test->SetPostGrpcInitFunc([]() {
grpc_timer_manager_set_threading(false);
grpc_core::ExecCtx exec_ctx;
grpc_core::Executor::SetThreadingAll(false);
ExecCtx exec_ctx;
Executor::SetThreadingAll(false);
});
test->SetUp();
test->RunTest();
test->TearDown();
GPR_ASSERT(!::testing::Test::HasFailure());
}
} // namespace grpc_core

@ -0,0 +1,24 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_TEST_CORE_END2END_END2END_TEST_FUZZER_H
#define GRPC_TEST_CORE_END2END_END2END_TEST_FUZZER_H
#include "test/core/end2end/end2end_test_fuzzer.pb.h"
namespace grpc_core {
void RunEnd2endFuzzer(const core_end2end_test_fuzzer::Msg& msg);
}
#endif // GRPC_TEST_CORE_END2END_END2END_TEST_FUZZER_H

@ -0,0 +1,20 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/libfuzzer/libfuzzer_macro.h"
#include "test/core/end2end/end2end_test_fuzzer.h"
DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) {
grpc_core::RunEnd2endFuzzer(msg);
}

@ -114,7 +114,9 @@ def grpc_core_end2end_test(name, shard_count = 10, tags = []):
grpc_proto_fuzzer(
name = "%s_fuzzer" % name,
srcs = [],
srcs = [
"end2end_test_fuzzer_main.cc",
],
corpus = "end2end_test_corpus/%s" % name,
data = END2END_TEST_DATA,
external_deps = [
@ -135,7 +137,7 @@ def grpc_core_end2end_test(name, shard_count = 10, tags = []):
uses_event_engine = False,
uses_polling = False,
deps = [
"end2end_test_fuzzer",
"%s_library" % name,
"end2end_test_fuzzer",
],
)

@ -16,8 +16,6 @@
//
//
#include <grpc/support/port_platform.h>
#include <limits.h>
#include <string.h>
@ -32,6 +30,7 @@
#include <grpc/slice.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#include "src/core/lib/gprpp/host_port.h"

@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/common_closures.h"
#include <memory>
@ -21,6 +19,8 @@
#include "absl/functional/any_invocable.h"
#include "gtest/gtest.h"
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/notification.h"
using ::grpc_event_engine::experimental::AnyInvocableClosure;

@ -11,8 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <algorithm>
#include <memory>
#include <thread>
@ -29,6 +27,7 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/default_event_engine.h"
#include "test/core/util/test_config.h"

@ -11,13 +11,13 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "absl/types/optional.h"
#include "gtest/gtest.h"
#include <grpc/support/port_platform.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/event_engine/channel_args_endpoint_config.h"

@ -12,14 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "gtest/gtest.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/default_event_engine.h"
#include "test/core/event_engine/util/aborting_event_engine.h"

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/forkable.h"
#include <grpc/support/port_platform.h>
#ifdef GPR_POSIX_SUBPROCESS
#include <errno.h>
#include <stdlib.h>

@ -14,13 +14,13 @@
// limitations under the License.
//
#include <grpc/support/port_platform.h>
#include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h"
#include "absl/synchronization/notification.h"
#include "gtest/gtest.h"
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/time.h"
using ::grpc_event_engine::experimental::FuzzingEventEngine;

@ -11,13 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "gtest/gtest.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/port_platform.h>
using ::grpc_event_engine::experimental::EventEngine;

@ -11,8 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/query_extensions.h"
#include <string>
@ -23,6 +21,7 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/event_engine/slice_buffer.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/crash.h"

@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <string.h>
#include <memory>
@ -26,6 +24,7 @@
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
using ::grpc_event_engine::experimental::Slice;
using ::grpc_event_engine::experimental::SliceBuffer;

@ -11,8 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "gmock/gmock.h"
@ -20,6 +18,7 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#include "test/core/util/test_config.h"

@ -11,12 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/tcp_socket_utils.h"
#include <errno.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h" // IWYU pragma: keep
#ifdef GRPC_HAVE_VSOCK

@ -11,14 +11,14 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "test/core/event_engine/test_init.h"
#include <string>
#include "absl/strings/str_cat.h"
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -13,11 +13,11 @@
// limitations under the License.
#ifndef GRPC_TEST_CORE_EVENT_ENGINE_TEST_INIT_H
#define GRPC_TEST_CORE_EVENT_ENGINE_TEST_INIT_H
#include <grpc/support/port_platform.h>
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -15,8 +15,6 @@
// IWYU pragma: no_include <ratio>
// IWYU pragma: no_include <arpa/inet.h>
#include <grpc/support/port_platform.h>
#include <cstdlib>
#include <cstring>
#include <memory>
@ -34,6 +32,7 @@
#include "gtest/gtest.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/config/config_vars.h"
#include "src/core/lib/event_engine/tcp_socket_utils.h"

@ -11,11 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <grpc/event_engine/slice.h>
#include <grpc/support/port_platform.h>
// The echo client wraps an EventEngine::Connect and EventEngine::Endpoint
// implementations, allowing third-party TCP listeners to interact with your

@ -12,13 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "absl/functional/any_invocable.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"

@ -12,14 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <memory>
#include "absl/functional/any_invocable.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#ifdef GPR_WINDOWS

@ -14,8 +14,6 @@
#ifndef GRPC_TEST_CORE_EVENT_ENGINE_UTIL_ABORTING_EVENT_ENGINE_H
#define GRPC_TEST_CORE_EVENT_ENGINE_UTIL_ABORTING_EVENT_ENGINE_H
#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <memory>
@ -27,6 +25,7 @@
#include <grpc/event_engine/endpoint_config.h>
#include <grpc/event_engine/event_engine.h>
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/support/port_platform.h>
namespace grpc_event_engine {
namespace experimental {

@ -11,8 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <deque>
@ -23,6 +21,7 @@
#include "absl/types/optional.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/event_engine/common_closures.h"
#include "src/core/lib/event_engine/work_queue/basic_work_queue.h"

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

Loading…
Cancel
Save