Merge remote-tracking branch 'upstream/master' into xds_aggregate_cluster_fix

pull/35313/head
Mark D. Roth 1 year ago
commit 85cfd70c59
  1. 2
      .bazelci/presubmit.yml
  2. 10
      .github/CODEOWNERS
  3. 2
      .github/ISSUE_TEMPLATE/bug_report_csharp.md
  4. 2
      .github/ISSUE_TEMPLATE/feature_request_csharp.md
  5. 606
      CMakeLists.txt
  6. 8
      Makefile
  7. 8
      Package.swift
  8. 13
      bazel/experiments.bzl
  9. 846
      build_autogenerated.yaml
  10. 4
      config.m4
  11. 4
      config.w32
  12. 27
      examples/python/helloworld/helloworld_pb2.py
  13. 14
      examples/python/helloworld/helloworld_pb2.pyi
  14. 104
      examples/python/helloworld/helloworld_pb2_grpc.py
  15. 8
      gRPC-C++.podspec
  16. 12
      gRPC-Core.podspec
  17. 8
      grpc.gemspec
  18. 11
      grpc.gyp
  19. 12
      include/grpc/event_engine/internal/slice_cast.h
  20. 5
      include/grpc/event_engine/slice.h
  21. 6
      include/grpc/impl/channel_arg_names.h
  22. 14
      include/grpcpp/ext/csm_observability.h
  23. 12
      include/grpcpp/ext/otel_plugin.h
  24. 1
      include/grpcpp/test/channel_test_peer.h
  25. 8
      package.xml
  26. 2
      requirements.bazel.txt
  27. 23
      src/compiler/python_generator.cc
  28. 144
      src/core/BUILD
  29. 59
      src/core/ext/filters/backend_metrics/backend_metric_filter.cc
  30. 26
      src/core/ext/filters/backend_metrics/backend_metric_filter.h
  31. 4
      src/core/ext/filters/channel_idle/channel_idle_filter.cc
  32. 4
      src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc
  33. 10
      src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc
  34. 5
      src/core/ext/filters/client_channel/lb_policy/endpoint_list.h
  35. 3
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  36. 18
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  37. 30
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
  38. 44
      src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
  39. 30
      src/core/ext/filters/fault_injection/fault_injection_filter.cc
  40. 17
      src/core/ext/filters/fault_injection/fault_injection_filter.h
  41. 28
      src/core/ext/filters/http/client_authority_filter.cc
  42. 16
      src/core/ext/filters/http/client_authority_filter.h
  43. 48
      src/core/ext/filters/http/http_filters_plugin.cc
  44. 134
      src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
  45. 24
      src/core/ext/filters/load_reporting/server_load_reporting_filter.h
  46. 4
      src/core/ext/filters/logging/logging_filter.cc
  47. 8
      src/core/ext/filters/message_size/message_size_filter.cc
  48. 26
      src/core/ext/filters/rbac/rbac_filter.cc
  49. 15
      src/core/ext/filters/rbac/rbac_filter.h
  50. 38
      src/core/ext/filters/server_config_selector/server_config_selector_filter.cc
  51. 95
      src/core/ext/filters/stateful_session/stateful_session_filter.cc
  52. 25
      src/core/ext/filters/stateful_session/stateful_session_filter.h
  53. 19
      src/core/ext/transport/chaotic_good/chaotic_good_transport.cc
  54. 111
      src/core/ext/transport/chaotic_good/chaotic_good_transport.h
  55. 325
      src/core/ext/transport/chaotic_good/client_transport.cc
  56. 202
      src/core/ext/transport/chaotic_good/client_transport.h
  57. 165
      src/core/ext/transport/chaotic_good/frame.cc
  58. 83
      src/core/ext/transport/chaotic_good/frame.h
  59. 12
      src/core/ext/transport/chaotic_good/frame_header.cc
  60. 2
      src/core/ext/transport/chaotic_good/frame_header.h
  61. 332
      src/core/ext/transport/chaotic_good/server_transport.cc
  62. 145
      src/core/ext/transport/chaotic_good/server_transport.h
  63. 13
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  64. 9
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  65. 6
      src/core/ext/transport/chttp2/transport/chttp2_transport.h
  66. 52
      src/core/ext/transport/chttp2/transport/flow_control.cc
  67. 7
      src/core/ext/transport/chttp2/transport/flow_control.h
  68. 1
      src/core/ext/transport/chttp2/transport/parsing.cc
  69. 5
      src/core/ext/transport/chttp2/transport/writing.cc
  70. 8
      src/core/ext/transport/inproc/inproc_transport.cc
  71. 7
      src/core/lib/channel/call_tracer.h
  72. 99
      src/core/lib/channel/promise_based_filter.h
  73. 4
      src/core/lib/channel/server_call_tracer_filter.cc
  74. 11
      src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
  75. 10
      src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h
  76. 8
      src/core/lib/event_engine/posix_engine/posix_engine.cc
  77. 114
      src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
  78. 51
      src/core/lib/event_engine/windows/native_windows_dns_resolver.h
  79. 8
      src/core/lib/event_engine/windows/windows_engine.cc
  80. 72
      src/core/lib/experiments/experiments.cc
  81. 35
      src/core/lib/experiments/experiments.h
  82. 25
      src/core/lib/experiments/experiments.yaml
  83. 6
      src/core/lib/experiments/rollouts.yaml
  84. 9
      src/core/lib/gprpp/debug_location.h
  85. 3041
      src/core/lib/promise/detail/seq_state.h
  86. 45
      src/core/lib/promise/detail/status.h
  87. 1455
      src/core/lib/promise/detail/switch.h
  88. 4
      src/core/lib/promise/event_engine_wakeup_scheduler.h
  89. 4
      src/core/lib/promise/if.h
  90. 10
      src/core/lib/promise/inter_activity_pipe.h
  91. 22
      src/core/lib/promise/mpsc.h
  92. 64
      src/core/lib/promise/party.cc
  93. 45
      src/core/lib/promise/party.h
  94. 45
      src/core/lib/promise/seq.h
  95. 24
      src/core/lib/promise/status_flag.h
  96. 72
      src/core/lib/promise/switch.h
  97. 6
      src/core/lib/promise/try_join.h
  98. 29
      src/core/lib/promise/try_seq.h
  99. 4
      src/core/lib/resource_quota/arena.h
  100. 11
      src/core/lib/resource_quota/memory_quota.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -12,7 +12,7 @@
---
# TODO(yannic): Ideally, we should also enable buildifier and all platforms should test `//...`.
tasks:
ubuntu1804:
ubuntu2004:
build_targets:
- //:all
- //src/proto/...

@ -1,13 +1,11 @@
# Auto-generated by the tools/mkowners/mkowners.py tool
# Uses OWNERS files in different modules throughout the
# repository as the source of truth for module ownership.
/**/OWNERS @markdroth @a11r
/bazel/** @jtattermusch @veblush @gnossen
/cmake/** @jtattermusch @apolcyn
/bazel/** @veblush @gnossen
/bazel/experiments.yaml
/cmake/** @veblush @apolcyn
/src/core/ext/filters/client_channel/** @markdroth
/src/core/ext/transport/chttp2/transport/** @ctiller
/src/core/ext/xds/** @markdroth
/src/core/lib/resolver/** @markdroth
/src/core/lib/service_config/** @markdroth
/tools/dockerfile/** @jtattermusch @apolcyn
/tools/dockerfile/** @drfloob @apolcyn @gnossen
/tools/run_tests/xds_k8s_test_driver/** @sergiitk @XuanWang-Amos @gnossen

@ -2,7 +2,7 @@
name: Report a gRPC C# bug
about: Create a report to help us improve
labels: kind/bug, priority/P2, lang/C#
assignees: jtattermusch
assignees: apolcyn
---

@ -2,7 +2,7 @@
name: Request a gRPC C# feature
about: Suggest an idea for this project
labels: kind/enhancement, priority/P2, lang/C#
assignees: jtattermusch
assignees: apolcyn
---

606
CMakeLists.txt generated

@ -883,6 +883,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx avl_test)
add_dependencies(buildtests_cxx aws_request_signer_test)
add_dependencies(buildtests_cxx b64_test)
add_dependencies(buildtests_cxx backend_metrics_lb_policy_test)
add_dependencies(buildtests_cxx backoff_test)
add_dependencies(buildtests_cxx bad_ping_test)
add_dependencies(buildtests_cxx bad_server_response_test)
@ -961,8 +962,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx client_ssl_test)
endif()
add_dependencies(buildtests_cxx client_streaming_test)
add_dependencies(buildtests_cxx client_transport_error_test)
add_dependencies(buildtests_cxx client_transport_test)
add_dependencies(buildtests_cxx cmdline_test)
add_dependencies(buildtests_cxx codegen_test_full)
add_dependencies(buildtests_cxx codegen_test_minimal)
@ -1047,7 +1046,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx forkable_test)
add_dependencies(buildtests_cxx format_request_test)
add_dependencies(buildtests_cxx frame_handler_test)
add_dependencies(buildtests_cxx frame_header_test)
add_dependencies(buildtests_cxx frame_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx fuzzing_event_engine_test)
endif()
@ -1197,7 +1196,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx percent_encoding_test)
add_dependencies(buildtests_cxx periodic_update_test)
add_dependencies(buildtests_cxx pick_first_test)
add_dependencies(buildtests_cxx pid_controller_test)
add_dependencies(buildtests_cxx ping_abuse_policy_test)
add_dependencies(buildtests_cxx ping_callbacks_test)
add_dependencies(buildtests_cxx ping_configuration_test)
@ -1375,6 +1373,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx streams_not_seen_test)
add_dependencies(buildtests_cxx string_ref_test)
add_dependencies(buildtests_cxx string_test)
add_dependencies(buildtests_cxx switch_test)
add_dependencies(buildtests_cxx sync_test)
add_dependencies(buildtests_cxx system_roots_test)
add_dependencies(buildtests_cxx table_test)
@ -1405,8 +1404,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx test_core_security_ssl_credentials_test)
add_dependencies(buildtests_cxx test_core_slice_slice_buffer_test)
add_dependencies(buildtests_cxx test_core_slice_slice_test)
add_dependencies(buildtests_cxx test_core_transport_chaotic_good_frame_test)
add_dependencies(buildtests_cxx test_core_transport_chttp2_frame_test)
add_dependencies(buildtests_cxx test_cpp_client_credentials_test)
add_dependencies(buildtests_cxx test_cpp_end2end_ssl_credentials_test)
add_dependencies(buildtests_cxx test_cpp_server_credentials_test)
@ -2257,7 +2254,7 @@ add_library(grpc
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
src/core/lib/event_engine/posix_engine/internal_errqueue.cc
src/core/lib/event_engine/posix_engine/lockfree_event.cc
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
src/core/lib/event_engine/posix_engine/posix_endpoint.cc
src/core/lib/event_engine/posix_engine/posix_engine.cc
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@ -2284,6 +2281,7 @@ add_library(grpc
src/core/lib/event_engine/utils.cc
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
src/core/lib/event_engine/windows/iocp.cc
src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
src/core/lib/event_engine/windows/win_socket.cc
src/core/lib/event_engine/windows/windows_endpoint.cc
src/core/lib/event_engine/windows/windows_engine.cc
@ -2509,7 +2507,6 @@ add_library(grpc
src/core/lib/transport/http_connect_handshaker.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/parsed_metadata.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/tcp_connect_handshaker.cc
src/core/lib/transport/timeout_encoding.cc
@ -2989,7 +2986,7 @@ add_library(grpc_unsecure
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
src/core/lib/event_engine/posix_engine/internal_errqueue.cc
src/core/lib/event_engine/posix_engine/lockfree_event.cc
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
src/core/lib/event_engine/posix_engine/posix_endpoint.cc
src/core/lib/event_engine/posix_engine/posix_engine.cc
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@ -3016,6 +3013,7 @@ add_library(grpc_unsecure
src/core/lib/event_engine/utils.cc
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
src/core/lib/event_engine/windows/iocp.cc
src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
src/core/lib/event_engine/windows/win_socket.cc
src/core/lib/event_engine/windows/windows_endpoint.cc
src/core/lib/event_engine/windows/windows_engine.cc
@ -3202,7 +3200,6 @@ add_library(grpc_unsecure
src/core/lib/transport/http_connect_handshaker.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/parsed_metadata.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/tcp_connect_handshaker.cc
src/core/lib/transport/timeout_encoding.cc
@ -4979,7 +4976,7 @@ add_library(grpc_authorization_provider
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
src/core/lib/event_engine/posix_engine/internal_errqueue.cc
src/core/lib/event_engine/posix_engine/lockfree_event.cc
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
src/core/lib/event_engine/posix_engine/posix_endpoint.cc
src/core/lib/event_engine/posix_engine/posix_engine.cc
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@ -5006,6 +5003,7 @@ add_library(grpc_authorization_provider
src/core/lib/event_engine/utils.cc
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
src/core/lib/event_engine/windows/iocp.cc
src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
src/core/lib/event_engine/windows/win_socket.cc
src/core/lib/event_engine/windows/windows_endpoint.cc
src/core/lib/event_engine/windows/windows_engine.cc
@ -6856,6 +6854,55 @@ target_link_libraries(b64_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(backend_metrics_lb_policy_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
src/cpp/server/orca/orca_service.cc
test/cpp/interop/backend_metrics_lb_policy.cc
test/cpp/interop/backend_metrics_lb_policy_test.cc
)
target_compile_features(backend_metrics_lb_policy_test PUBLIC cxx_std_14)
target_include_directories(backend_metrics_lb_policy_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(backend_metrics_lb_policy_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
grpc++
grpc_test_util
grpc++_test_config
)
endif()
if(gRPC_BUILD_TESTS)
@ -9532,92 +9579,6 @@ target_link_libraries(client_streaming_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(client_transport_error_test
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.cc
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h
src/core/ext/transport/chaotic_good/client_transport.cc
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/lib/transport/promise_endpoint.cc
test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc
test/core/transport/chaotic_good/client_transport_error_test.cc
)
target_compile_features(client_transport_error_test PUBLIC cxx_std_14)
target_include_directories(client_transport_error_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(client_transport_error_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
${_gRPC_PROTOBUF_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(client_transport_test
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.cc
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h
${_gRPC_PROTO_GENS_DIR}/test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.grpc.pb.h
src/core/ext/transport/chaotic_good/client_transport.cc
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/lib/transport/promise_endpoint.cc
test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc
test/core/transport/chaotic_good/client_transport_test.cc
)
target_compile_features(client_transport_test PUBLIC cxx_std_14)
target_include_directories(client_transport_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(client_transport_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
${_gRPC_PROTOBUF_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -12234,7 +12195,6 @@ add_executable(flow_control_test
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/transport/bdp_estimator.cc
src/core/lib/transport/pid_controller.cc
test/core/transport/chttp2/flow_control_test.cc
third_party/upb/upb/hash/common.c
third_party/upb/upb/message/accessors.c
@ -12528,12 +12488,17 @@ target_link_libraries(frame_handler_test
endif()
if(gRPC_BUILD_TESTS)
add_executable(frame_header_test
src/core/ext/transport/chaotic_good/frame_header.cc
test/core/transport/chaotic_good/frame_header_test.cc
add_executable(frame_test
src/core/ext/transport/chttp2/transport/frame.cc
src/core/lib/debug/trace.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
test/core/transport/chttp2/frame_test.cc
)
target_compile_features(frame_header_test PUBLIC cxx_std_14)
target_include_directories(frame_header_test
target_compile_features(frame_test PUBLIC cxx_std_14)
target_include_directories(frame_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
@ -12552,10 +12517,12 @@ target_include_directories(frame_header_test
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(frame_header_test
target_link_libraries(frame_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::hash
absl::statusor
absl::span
gpr
)
@ -17809,49 +17776,6 @@ target_link_libraries(pick_first_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(pid_controller_test
test/core/transport/pid_controller_test.cc
test/core/util/cmdline.cc
test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
test/core/util/mock_endpoint.cc
test/core/util/parse_hexstring.cc
test/core/util/passthru_endpoint.cc
test/core/util/resolve_localhost_ip46.cc
test/core/util/slice_splitter.cc
test/core/util/tracer_util.cc
)
target_compile_features(pid_controller_test PUBLIC cxx_std_14)
target_include_directories(pid_controller_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(pid_controller_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -23776,6 +23700,41 @@ target_link_libraries(string_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(switch_test
test/core/promise/switch_test.cc
)
target_compile_features(switch_test PUBLIC cxx_std_14)
target_include_directories(switch_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(switch_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::type_traits
absl::statusor
gpr
)
endif()
if(gRPC_BUILD_TESTS)
@ -24635,359 +24594,6 @@ target_link_libraries(test_core_slice_slice_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_transport_chaotic_good_frame_test
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/decode_huff.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
src/core/ext/transport/chttp2/transport/hpack_parse_result.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
src/core/ext/transport/chttp2/transport/http_trace.cc
src/core/ext/transport/chttp2/transport/huffsyms.cc
src/core/ext/transport/chttp2/transport/varint.cc
src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c
src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c
src/core/ext/upb-gen/google/rpc/status.upb_minitable.c
src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c
src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c
src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c
src/core/lib/address_utils/parse_address.cc
src/core/lib/address_utils/sockaddr_utils.cc
src/core/lib/backoff/backoff.cc
src/core/lib/backoff/random_early_detection.cc
src/core/lib/channel/call_tracer.cc
src/core/lib/channel/channel_args.cc
src/core/lib/channel/channel_args_preconditioning.cc
src/core/lib/channel/channel_stack.cc
src/core/lib/channel/channel_stack_builder.cc
src/core/lib/channel/channel_stack_builder_impl.cc
src/core/lib/channel/channel_stack_trace.cc
src/core/lib/channel/channel_trace.cc
src/core/lib/channel/channelz.cc
src/core/lib/channel/channelz_registry.cc
src/core/lib/channel/connected_channel.cc
src/core/lib/channel/promise_based_filter.cc
src/core/lib/channel/server_call_tracer_filter.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/config/core_configuration.cc
src/core/lib/debug/event_log.cc
src/core/lib/debug/histogram_view.cc
src/core/lib/debug/stats.cc
src/core/lib/debug/stats_data.cc
src/core/lib/debug/trace.cc
src/core/lib/event_engine/ares_resolver.cc
src/core/lib/event_engine/cf_engine/cf_engine.cc
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
src/core/lib/event_engine/event_engine.cc
src/core/lib/event_engine/forkable.cc
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
src/core/lib/event_engine/posix_engine/internal_errqueue.cc
src/core/lib/event_engine/posix_engine/lockfree_event.cc
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
src/core/lib/event_engine/posix_engine/posix_endpoint.cc
src/core/lib/event_engine/posix_engine/posix_engine.cc
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc
src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc
src/core/lib/event_engine/posix_engine/timer.cc
src/core/lib/event_engine/posix_engine/timer_heap.cc
src/core/lib/event_engine/posix_engine/timer_manager.cc
src/core/lib/event_engine/posix_engine/traced_buffer_list.cc
src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc
src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc
src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc
src/core/lib/event_engine/resolved_address.cc
src/core/lib/event_engine/shim.cc
src/core/lib/event_engine/slice.cc
src/core/lib/event_engine/slice_buffer.cc
src/core/lib/event_engine/tcp_socket_utils.cc
src/core/lib/event_engine/thread_pool/thread_count.cc
src/core/lib/event_engine/thread_pool/thread_pool_factory.cc
src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc
src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc
src/core/lib/event_engine/time_util.cc
src/core/lib/event_engine/trace.cc
src/core/lib/event_engine/utils.cc
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
src/core/lib/event_engine/windows/iocp.cc
src/core/lib/event_engine/windows/win_socket.cc
src/core/lib/event_engine/windows/windows_endpoint.cc
src/core/lib/event_engine/windows/windows_engine.cc
src/core/lib/event_engine/windows/windows_listener.cc
src/core/lib/event_engine/work_queue/basic_work_queue.cc
src/core/lib/experiments/config.cc
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/load_file.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/ref_counted_string.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/gprpp/time_averaged_stats.cc
src/core/lib/gprpp/validation_errors.cc
src/core/lib/gprpp/work_serializer.cc
src/core/lib/handshaker/proxy_mapper_registry.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/cfstream_handle.cc
src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/dualstack_socket_posix.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_cfstream.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
src/core/lib/iomgr/endpoint_pair_windows.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/error_cfstream.cc
src/core/lib/iomgr/ev_apple.cc
src/core/lib/iomgr/ev_epoll1_linux.cc
src/core/lib/iomgr/ev_poll_posix.cc
src/core/lib/iomgr/ev_posix.cc
src/core/lib/iomgr/ev_windows.cc
src/core/lib/iomgr/event_engine_shims/closure.cc
src/core/lib/iomgr/event_engine_shims/endpoint.cc
src/core/lib/iomgr/event_engine_shims/tcp_client.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/fork_posix.cc
src/core/lib/iomgr/fork_windows.cc
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/grpc_if_nametoindex_posix.cc
src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/iomgr/iomgr_posix.cc
src/core/lib/iomgr/iomgr_posix_cfstream.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/load_file.cc
src/core/lib/iomgr/lockfree_event.cc
src/core/lib/iomgr/polling_entity.cc
src/core/lib/iomgr/pollset.cc
src/core/lib/iomgr/pollset_set.cc
src/core/lib/iomgr/pollset_set_windows.cc
src/core/lib/iomgr/pollset_windows.cc
src/core/lib/iomgr/resolve_address.cc
src/core/lib/iomgr/resolve_address_posix.cc
src/core/lib/iomgr/resolve_address_windows.cc
src/core/lib/iomgr/sockaddr_utils_posix.cc
src/core/lib/iomgr/socket_factory_posix.cc
src/core/lib/iomgr/socket_mutator.cc
src/core/lib/iomgr/socket_utils_common_posix.cc
src/core/lib/iomgr/socket_utils_linux.cc
src/core/lib/iomgr/socket_utils_posix.cc
src/core/lib/iomgr/socket_utils_windows.cc
src/core/lib/iomgr/socket_windows.cc
src/core/lib/iomgr/systemd_utils.cc
src/core/lib/iomgr/tcp_client.cc
src/core/lib/iomgr/tcp_client_cfstream.cc
src/core/lib/iomgr/tcp_client_posix.cc
src/core/lib/iomgr/tcp_client_windows.cc
src/core/lib/iomgr/tcp_posix.cc
src/core/lib/iomgr/tcp_server.cc
src/core/lib/iomgr/tcp_server_posix.cc
src/core/lib/iomgr/tcp_server_utils_posix_common.cc
src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc
src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc
src/core/lib/iomgr/tcp_server_windows.cc
src/core/lib/iomgr/tcp_windows.cc
src/core/lib/iomgr/timer.cc
src/core/lib/iomgr/timer_generic.cc
src/core/lib/iomgr/timer_heap.cc
src/core/lib/iomgr/timer_manager.cc
src/core/lib/iomgr/unix_sockets_posix.cc
src/core/lib/iomgr/unix_sockets_posix_noop.cc
src/core/lib/iomgr/vsock.cc
src/core/lib/iomgr/wakeup_fd_eventfd.cc
src/core/lib/iomgr/wakeup_fd_nospecial.cc
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/json/json_writer.cc
src/core/lib/load_balancing/lb_policy.cc
src/core/lib/load_balancing/lb_policy_registry.cc
src/core/lib/promise/activity.cc
src/core/lib/promise/party.cc
src/core/lib/promise/trace.cc
src/core/lib/resolver/endpoint_addresses.cc
src/core/lib/resolver/resolver.cc
src/core/lib/resolver/resolver_registry.cc
src/core/lib/resource_quota/api.cc
src/core/lib/resource_quota/arena.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/periodic_update.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/security/certificate_provider/certificate_provider_registry.cc
src/core/lib/security/credentials/alts/check_gcp_environment.cc
src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc
src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc
src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc
src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
src/core/lib/service_config/service_config_parser.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
src/core/lib/surface/builtins.cc
src/core/lib/surface/byte_buffer.cc
src/core/lib/surface/byte_buffer_reader.cc
src/core/lib/surface/call.cc
src/core/lib/surface/call_details.cc
src/core/lib/surface/call_log_batch.cc
src/core/lib/surface/call_trace.cc
src/core/lib/surface/channel.cc
src/core/lib/surface/channel_init.cc
src/core/lib/surface/channel_ping.cc
src/core/lib/surface/channel_stack_type.cc
src/core/lib/surface/completion_queue.cc
src/core/lib/surface/completion_queue_factory.cc
src/core/lib/surface/event_string.cc
src/core/lib/surface/init_internally.cc
src/core/lib/surface/lame_client.cc
src/core/lib/surface/metadata_array.cc
src/core/lib/surface/server.cc
src/core/lib/surface/validate_metadata.cc
src/core/lib/surface/version.cc
src/core/lib/transport/batch_builder.cc
src/core/lib/transport/connectivity_state.cc
src/core/lib/transport/error_utils.cc
src/core/lib/transport/handshaker_registry.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/parsed_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
src/core/lib/uri/uri_parser.cc
src/core/tsi/alts/handshaker/transport_security_common_api.cc
test/core/transport/chaotic_good/frame_test.cc
third_party/upb/upb/hash/common.c
third_party/upb/upb/message/accessors.c
third_party/upb/upb/message/array.c
third_party/upb/upb/message/map.c
third_party/upb/upb/message/map_sorter.c
third_party/upb/upb/message/message.c
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
third_party/upb/upb/mini_descriptor/internal/base92.c
third_party/upb/upb/mini_descriptor/internal/encode.c
third_party/upb/upb/mini_descriptor/link.c
third_party/upb/upb/mini_table/extension_registry.c
third_party/upb/upb/mini_table/internal/message.c
third_party/upb/upb/mini_table/message.c
third_party/upb/upb/wire/decode.c
third_party/upb/upb/wire/decode_fast.c
third_party/upb/upb/wire/encode.c
third_party/upb/upb/wire/eps_copy_input_stream.c
third_party/upb/upb/wire/reader.c
)
target_compile_features(test_core_transport_chaotic_good_frame_test PUBLIC cxx_std_14)
target_include_directories(test_core_transport_chaotic_good_frame_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(test_core_transport_chaotic_good_frame_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
upb
utf8_range_lib
${_gRPC_ZLIB_LIBRARIES}
absl::cleanup
absl::flat_hash_map
absl::inlined_vector
absl::function_ref
absl::hash
absl::type_traits
absl::random_bit_gen_ref
absl::random_distributions
absl::statusor
absl::span
absl::utility
${_gRPC_CARES_LIBRARIES}
gpr
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_transport_chttp2_frame_test
src/core/ext/transport/chttp2/transport/frame.cc
src/core/lib/debug/trace.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
test/core/transport/chttp2/frame_test.cc
)
target_compile_features(test_core_transport_chttp2_frame_test PUBLIC cxx_std_14)
target_include_directories(test_core_transport_chttp2_frame_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(test_core_transport_chttp2_frame_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::hash
absl::statusor
absl::span
gpr
)
endif()
if(gRPC_BUILD_TESTS)

8
Makefile generated

@ -1455,7 +1455,7 @@ LIBGRPC_SRC = \
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \
src/core/lib/event_engine/posix_engine/internal_errqueue.cc \
src/core/lib/event_engine/posix_engine/lockfree_event.cc \
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \
src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \
src/core/lib/event_engine/posix_engine/posix_endpoint.cc \
src/core/lib/event_engine/posix_engine/posix_engine.cc \
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \
@ -1482,6 +1482,7 @@ LIBGRPC_SRC = \
src/core/lib/event_engine/utils.cc \
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \
src/core/lib/event_engine/windows/iocp.cc \
src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \
src/core/lib/event_engine/windows/win_socket.cc \
src/core/lib/event_engine/windows/windows_endpoint.cc \
src/core/lib/event_engine/windows/windows_engine.cc \
@ -1707,7 +1708,6 @@ LIBGRPC_SRC = \
src/core/lib/transport/http_connect_handshaker.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/parsed_metadata.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/tcp_connect_handshaker.cc \
src/core/lib/transport/timeout_encoding.cc \
@ -2037,7 +2037,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \
src/core/lib/event_engine/posix_engine/internal_errqueue.cc \
src/core/lib/event_engine/posix_engine/lockfree_event.cc \
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \
src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \
src/core/lib/event_engine/posix_engine/posix_endpoint.cc \
src/core/lib/event_engine/posix_engine/posix_engine.cc \
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \
@ -2064,6 +2064,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/event_engine/utils.cc \
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \
src/core/lib/event_engine/windows/iocp.cc \
src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \
src/core/lib/event_engine/windows/win_socket.cc \
src/core/lib/event_engine/windows/windows_endpoint.cc \
src/core/lib/event_engine/windows/windows_engine.cc \
@ -2250,7 +2251,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/transport/http_connect_handshaker.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/parsed_metadata.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/tcp_connect_handshaker.cc \
src/core/lib/transport/timeout_encoding.cc \

8
Package.swift generated

@ -1289,8 +1289,8 @@ let package = Package(
"src/core/lib/event_engine/posix_engine/internal_errqueue.h",
"src/core/lib/event_engine/posix_engine/lockfree_event.cc",
"src/core/lib/event_engine/posix_engine/lockfree_event.h",
"src/core/lib/event_engine/posix_engine/native_dns_resolver.cc",
"src/core/lib/event_engine/posix_engine/native_dns_resolver.h",
"src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc",
"src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h",
"src/core/lib/event_engine/posix_engine/posix_endpoint.cc",
"src/core/lib/event_engine/posix_engine/posix_endpoint.h",
"src/core/lib/event_engine/posix_engine/posix_engine.cc",
@ -1346,6 +1346,8 @@ let package = Package(
"src/core/lib/event_engine/windows/grpc_polled_fd_windows.h",
"src/core/lib/event_engine/windows/iocp.cc",
"src/core/lib/event_engine/windows/iocp.h",
"src/core/lib/event_engine/windows/native_windows_dns_resolver.cc",
"src/core/lib/event_engine/windows/native_windows_dns_resolver.h",
"src/core/lib/event_engine/windows/win_socket.cc",
"src/core/lib/event_engine/windows/win_socket.h",
"src/core/lib/event_engine/windows/windows_endpoint.cc",
@ -1903,8 +1905,6 @@ let package = Package(
"src/core/lib/transport/metadata_compression_traits.h",
"src/core/lib/transport/parsed_metadata.cc",
"src/core/lib/transport/parsed_metadata.h",
"src/core/lib/transport/pid_controller.cc",
"src/core/lib/transport/pid_controller.h",
"src/core/lib/transport/simple_slice_based_metadata.h",
"src/core/lib/transport/status_conversion.cc",
"src/core/lib/transport/status_conversion.h",

@ -28,16 +28,13 @@ EXPERIMENT_ENABLES = {
"http2_stats_fix": "http2_stats_fix",
"keepalive_fix": "keepalive_fix",
"keepalive_server_fix": "keepalive_server_fix",
"memory_pressure_controller": "memory_pressure_controller",
"monitoring_experiment": "monitoring_experiment",
"multiping": "multiping",
"overload_protection": "overload_protection",
"peer_state_based_framing": "peer_state_based_framing",
"pending_queue_cap": "pending_queue_cap",
"pick_first_happy_eyeballs": "pick_first_happy_eyeballs",
"promise_based_client_call": "promise_based_client_call",
"promise_based_server_call": "promise_based_server_call",
"red_max_concurrent_streams": "red_max_concurrent_streams",
"registered_method_lookup_in_transport": "registered_method_lookup_in_transport",
"promise_based_inproc_transport": "promise_based_client_call,promise_based_inproc_transport,promise_based_server_call,registered_method_lookup_in_transport",
"registered_methods_map": "registered_methods_map",
@ -50,6 +47,7 @@ EXPERIMENT_ENABLES = {
"tcp_rcv_lowat": "tcp_rcv_lowat",
"trace_record_callops": "trace_record_callops",
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
"v3_backend_metric_filter": "v3_backend_metric_filter",
"v3_channel_idle_filters": "v3_channel_idle_filters",
"v3_compression_filter": "v3_compression_filter",
"v3_server_auth_filter": "v3_server_auth_filter",
@ -87,7 +85,6 @@ EXPERIMENTS = {
"flow_control_test": [
"multiping",
"peer_state_based_framing",
"red_max_concurrent_streams",
"rstpit",
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
@ -103,7 +100,6 @@ EXPERIMENTS = {
],
"resource_quota_test": [
"free_large_allocator",
"memory_pressure_controller",
"unconstrained_max_quota_buffer_size",
],
"xds_end2end_test": [
@ -124,7 +120,6 @@ EXPERIMENTS = {
"event_engine_listener",
],
"flow_control_test": [
"overload_protection",
"write_size_cap",
"write_size_policy",
],
@ -169,7 +164,6 @@ EXPERIMENTS = {
"flow_control_test": [
"multiping",
"peer_state_based_framing",
"red_max_concurrent_streams",
"rstpit",
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
@ -185,7 +179,6 @@ EXPERIMENTS = {
],
"resource_quota_test": [
"free_large_allocator",
"memory_pressure_controller",
"unconstrained_max_quota_buffer_size",
],
"xds_end2end_test": [
@ -200,7 +193,6 @@ EXPERIMENTS = {
"wrr_delegate_to_pick_first",
],
"flow_control_test": [
"overload_protection",
"write_size_cap",
"write_size_policy",
],
@ -252,7 +244,6 @@ EXPERIMENTS = {
"flow_control_test": [
"multiping",
"peer_state_based_framing",
"red_max_concurrent_streams",
"rstpit",
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
@ -271,7 +262,6 @@ EXPERIMENTS = {
],
"resource_quota_test": [
"free_large_allocator",
"memory_pressure_controller",
"unconstrained_max_quota_buffer_size",
],
"xds_end2end_test": [
@ -292,7 +282,6 @@ EXPERIMENTS = {
"event_engine_listener",
],
"flow_control_test": [
"overload_protection",
"write_size_cap",
"write_size_policy",
],

@ -886,7 +886,7 @@ libs:
- src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h
- src/core/lib/event_engine/posix_engine/internal_errqueue.h
- src/core/lib/event_engine/posix_engine/lockfree_event.h
- src/core/lib/event_engine/posix_engine/native_dns_resolver.h
- src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h
- src/core/lib/event_engine/posix_engine/posix_endpoint.h
- src/core/lib/event_engine/posix_engine/posix_engine.h
- src/core/lib/event_engine/posix_engine/posix_engine_closure.h
@ -914,6 +914,7 @@ libs:
- src/core/lib/event_engine/utils.h
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.h
- src/core/lib/event_engine/windows/iocp.h
- src/core/lib/event_engine/windows/native_windows_dns_resolver.h
- src/core/lib/event_engine/windows/win_socket.h
- src/core/lib/event_engine/windows/windows_endpoint.h
- src/core/lib/event_engine/windows/windows_engine.h
@ -1178,7 +1179,6 @@ libs:
- src/core/lib/transport/metadata_batch.h
- src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/pid_controller.h
- src/core/lib/transport/simple_slice_based_metadata.h
- src/core/lib/transport/status_conversion.h
- src/core/lib/transport/tcp_connect_handshaker.h
@ -1718,7 +1718,7 @@ libs:
- src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
- src/core/lib/event_engine/posix_engine/internal_errqueue.cc
- src/core/lib/event_engine/posix_engine/lockfree_event.cc
- src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/posix_endpoint.cc
- src/core/lib/event_engine/posix_engine/posix_engine.cc
- src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@ -1745,6 +1745,7 @@ libs:
- src/core/lib/event_engine/utils.cc
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
- src/core/lib/event_engine/windows/iocp.cc
- src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
- src/core/lib/event_engine/windows/win_socket.cc
- src/core/lib/event_engine/windows/windows_endpoint.cc
- src/core/lib/event_engine/windows/windows_engine.cc
@ -1970,7 +1971,6 @@ libs:
- src/core/lib/transport/http_connect_handshaker.cc
- src/core/lib/transport/metadata_batch.cc
- src/core/lib/transport/parsed_metadata.cc
- src/core/lib/transport/pid_controller.cc
- src/core/lib/transport/status_conversion.cc
- src/core/lib/transport/tcp_connect_handshaker.cc
- src/core/lib/transport/timeout_encoding.cc
@ -2355,7 +2355,7 @@ libs:
- src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h
- src/core/lib/event_engine/posix_engine/internal_errqueue.h
- src/core/lib/event_engine/posix_engine/lockfree_event.h
- src/core/lib/event_engine/posix_engine/native_dns_resolver.h
- src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h
- src/core/lib/event_engine/posix_engine/posix_endpoint.h
- src/core/lib/event_engine/posix_engine/posix_engine.h
- src/core/lib/event_engine/posix_engine/posix_engine_closure.h
@ -2383,6 +2383,7 @@ libs:
- src/core/lib/event_engine/utils.h
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.h
- src/core/lib/event_engine/windows/iocp.h
- src/core/lib/event_engine/windows/native_windows_dns_resolver.h
- src/core/lib/event_engine/windows/win_socket.h
- src/core/lib/event_engine/windows/windows_endpoint.h
- src/core/lib/event_engine/windows/windows_engine.h
@ -2611,7 +2612,6 @@ libs:
- src/core/lib/transport/metadata_batch.h
- src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/pid_controller.h
- src/core/lib/transport/simple_slice_based_metadata.h
- src/core/lib/transport/status_conversion.h
- src/core/lib/transport/tcp_connect_handshaker.h
@ -2808,7 +2808,7 @@ libs:
- src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
- src/core/lib/event_engine/posix_engine/internal_errqueue.cc
- src/core/lib/event_engine/posix_engine/lockfree_event.cc
- src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/posix_endpoint.cc
- src/core/lib/event_engine/posix_engine/posix_engine.cc
- src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@ -2835,6 +2835,7 @@ libs:
- src/core/lib/event_engine/utils.cc
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
- src/core/lib/event_engine/windows/iocp.cc
- src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
- src/core/lib/event_engine/windows/win_socket.cc
- src/core/lib/event_engine/windows/windows_endpoint.cc
- src/core/lib/event_engine/windows/windows_engine.cc
@ -3021,7 +3022,6 @@ libs:
- src/core/lib/transport/http_connect_handshaker.cc
- src/core/lib/transport/metadata_batch.cc
- src/core/lib/transport/parsed_metadata.cc
- src/core/lib/transport/pid_controller.cc
- src/core/lib/transport/status_conversion.cc
- src/core/lib/transport/tcp_connect_handshaker.cc
- src/core/lib/transport/timeout_encoding.cc
@ -4499,7 +4499,7 @@ libs:
- src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h
- src/core/lib/event_engine/posix_engine/internal_errqueue.h
- src/core/lib/event_engine/posix_engine/lockfree_event.h
- src/core/lib/event_engine/posix_engine/native_dns_resolver.h
- src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h
- src/core/lib/event_engine/posix_engine/posix_endpoint.h
- src/core/lib/event_engine/posix_engine/posix_engine.h
- src/core/lib/event_engine/posix_engine/posix_engine_closure.h
@ -4527,6 +4527,7 @@ libs:
- src/core/lib/event_engine/utils.h
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.h
- src/core/lib/event_engine/windows/iocp.h
- src/core/lib/event_engine/windows/native_windows_dns_resolver.h
- src/core/lib/event_engine/windows/win_socket.h
- src/core/lib/event_engine/windows/windows_endpoint.h
- src/core/lib/event_engine/windows/windows_engine.h
@ -4857,7 +4858,7 @@ libs:
- src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
- src/core/lib/event_engine/posix_engine/internal_errqueue.cc
- src/core/lib/event_engine/posix_engine/lockfree_event.cc
- src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/posix_endpoint.cc
- src/core/lib/event_engine/posix_engine/posix_engine.cc
- src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
@ -4884,6 +4885,7 @@ libs:
- src/core/lib/event_engine/utils.cc
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
- src/core/lib/event_engine/windows/iocp.cc
- src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
- src/core/lib/event_engine/windows/win_socket.cc
- src/core/lib/event_engine/windows/windows_endpoint.cc
- src/core/lib/event_engine/windows/windows_engine.cc
@ -5852,6 +5854,24 @@ targets:
- gtest
- grpc_test_util
uses_polling: false
- name: backend_metrics_lb_policy_test
gtest: true
build: test
language: c++
headers:
- test/cpp/interop/backend_metrics_lb_policy.h
src:
- src/proto/grpc/testing/empty.proto
- src/proto/grpc/testing/messages.proto
- src/proto/grpc/testing/test.proto
- src/cpp/server/orca/orca_service.cc
- test/cpp/interop/backend_metrics_lb_policy.cc
- test/cpp/interop/backend_metrics_lb_policy_test.cc
deps:
- gtest
- grpc++
- grpc_test_util
- grpc++_test_config
- name: backoff_test
gtest: true
build: test
@ -7650,62 +7670,6 @@ targets:
- grpc_authorization_provider
- grpc_unsecure
- grpc_test_util
- name: client_transport_error_test
gtest: true
build: test
language: c++
headers:
- src/core/ext/transport/chaotic_good/client_transport.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/lib/promise/event_engine_wakeup_scheduler.h
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/join.h
- src/core/lib/promise/mpsc.h
- src/core/lib/promise/wait_set.h
- src/core/lib/transport/promise_endpoint.h
- test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h
src:
- test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto
- src/core/ext/transport/chaotic_good/client_transport.cc
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/lib/transport/promise_endpoint.cc
- test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc
- test/core/transport/chaotic_good/client_transport_error_test.cc
deps:
- gtest
- protobuf
- grpc_test_util
uses_polling: false
- name: client_transport_test
gtest: true
build: test
language: c++
headers:
- src/core/ext/transport/chaotic_good/client_transport.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/lib/promise/event_engine_wakeup_scheduler.h
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/join.h
- src/core/lib/promise/mpsc.h
- src/core/lib/promise/wait_set.h
- src/core/lib/transport/promise_endpoint.h
- test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h
src:
- test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto
- src/core/ext/transport/chaotic_good/client_transport.cc
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/lib/transport/promise_endpoint.cc
- test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.cc
- test/core/transport/chaotic_good/client_transport_test.cc
deps:
- gtest
- protobuf
- grpc_test_util
uses_polling: false
- name: cmdline_test
gtest: true
build: test
@ -9288,7 +9252,6 @@ targets:
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/transport/bdp_estimator.h
- src/core/lib/transport/http2_errors.h
- src/core/lib/transport/pid_controller.h
- third_party/upb/upb/base/internal/log2.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/hash/common.h
@ -9370,7 +9333,6 @@ targets:
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/transport/bdp_estimator.cc
- src/core/lib/transport/pid_controller.cc
- test/core/transport/chttp2/flow_control_test.cc
- third_party/upb/upb/hash/common.c
- third_party/upb/upb/message/accessors.c
@ -9653,20 +9615,34 @@ targets:
deps:
- gtest
- grpc_test_util
- name: frame_header_test
- name: frame_test
gtest: true
build: test
language: c++
headers:
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/lib/gprpp/bitset.h
- src/core/ext/transport/chttp2/transport/frame.h
- src/core/lib/debug/trace.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_buffer.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/transport/http2_errors.h
src:
- src/core/ext/transport/chaotic_good/frame_header.cc
- test/core/transport/chaotic_good/frame_header_test.cc
- src/core/ext/transport/chttp2/transport/frame.cc
- src/core/lib/debug/trace.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- test/core/transport/chttp2/frame_test.cc
deps:
- gtest
- absl/hash:hash
- absl/status:statusor
- absl/types:span
- gpr
uses_polling: false
- name: fuzzing_event_engine_test
gtest: true
build: test
@ -12717,38 +12693,6 @@ targets:
- protobuf
- grpc_test_util
uses_polling: false
- name: pid_controller_test
gtest: true
build: test
language: c++
headers:
- test/core/util/cmdline.h
- test/core/util/evaluate_args_test_util.h
- test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/mock_authorization_endpoint.h
- test/core/util/mock_endpoint.h
- test/core/util/parse_hexstring.h
- test/core/util/passthru_endpoint.h
- test/core/util/resolve_localhost_ip46.h
- test/core/util/slice_splitter.h
- test/core/util/tracer_util.h
src:
- test/core/transport/pid_controller_test.cc
- test/core/util/cmdline.cc
- test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc
- test/core/util/mock_endpoint.cc
- test/core/util/parse_hexstring.cc
- test/core/util/passthru_endpoint.cc
- test/core/util/resolve_localhost_ip46.cc
- test/core/util/slice_splitter.cc
- test/core/util/tracer_util.cc
deps:
- gtest
- grpc_test_util
- name: ping_abuse_policy_test
gtest: true
build: test
@ -16287,6 +16231,24 @@ targets:
- gtest
- grpc_test_util
uses_polling: false
- name: switch_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/if.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/switch.h
src:
- test/core/promise/switch_test.cc
deps:
- gtest
- absl/meta:type_traits
- absl/status:statusor
- gpr
uses_polling: false
- name: sync_test
gtest: true
build: test
@ -16795,680 +16757,6 @@ targets:
- gtest
- grpc
uses_polling: false
- name: test_core_transport_chaotic_good_frame_test
gtest: true
build: test
language: c++
headers:
- src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/ext/transport/chttp2/transport/bin_encoder.h
- src/core/ext/transport/chttp2/transport/decode_huff.h
- src/core/ext/transport/chttp2/transport/hpack_constants.h
- src/core/ext/transport/chttp2/transport/hpack_encoder.h
- src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
- src/core/ext/transport/chttp2/transport/hpack_parse_result.h
- src/core/ext/transport/chttp2/transport/hpack_parser.h
- src/core/ext/transport/chttp2/transport/hpack_parser_table.h
- src/core/ext/transport/chttp2/transport/http_trace.h
- src/core/ext/transport/chttp2/transport/huffsyms.h
- src/core/ext/transport/chttp2/transport/legacy_frame.h
- src/core/ext/transport/chttp2/transport/varint.h
- src/core/ext/upb-gen/google/protobuf/any.upb.h
- src/core/ext/upb-gen/google/protobuf/any.upb_minitable.h
- src/core/ext/upb-gen/google/protobuf/descriptor.upb.h
- src/core/ext/upb-gen/google/rpc/status.upb.h
- src/core/ext/upb-gen/google/rpc/status.upb_minitable.h
- src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb.h
- src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.h
- src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb.h
- src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.h
- src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb.h
- src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.h
- src/core/lib/address_utils/parse_address.h
- src/core/lib/address_utils/sockaddr_utils.h
- src/core/lib/avl/avl.h
- src/core/lib/backoff/backoff.h
- src/core/lib/backoff/random_early_detection.h
- src/core/lib/channel/call_finalization.h
- src/core/lib/channel/call_tracer.h
- src/core/lib/channel/channel_args.h
- src/core/lib/channel/channel_args_preconditioning.h
- src/core/lib/channel/channel_fwd.h
- src/core/lib/channel/channel_stack.h
- src/core/lib/channel/channel_stack_builder.h
- src/core/lib/channel/channel_stack_builder_impl.h
- src/core/lib/channel/channel_stack_trace.h
- src/core/lib/channel/channel_trace.h
- src/core/lib/channel/channelz.h
- src/core/lib/channel/channelz_registry.h
- src/core/lib/channel/connected_channel.h
- src/core/lib/channel/context.h
- src/core/lib/channel/promise_based_filter.h
- src/core/lib/channel/status_util.h
- src/core/lib/channel/tcp_tracer.h
- src/core/lib/compression/compression_internal.h
- src/core/lib/compression/message_compress.h
- src/core/lib/config/core_configuration.h
- src/core/lib/debug/event_log.h
- src/core/lib/debug/histogram_view.h
- src/core/lib/debug/stats.h
- src/core/lib/debug/stats_data.h
- src/core/lib/debug/trace.h
- src/core/lib/event_engine/ares_resolver.h
- src/core/lib/event_engine/cf_engine/cf_engine.h
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.h
- src/core/lib/event_engine/cf_engine/cftype_unique_ref.h
- src/core/lib/event_engine/cf_engine/dns_service_resolver.h
- src/core/lib/event_engine/channel_args_endpoint_config.h
- src/core/lib/event_engine/common_closures.h
- src/core/lib/event_engine/default_event_engine.h
- src/core/lib/event_engine/default_event_engine_factory.h
- src/core/lib/event_engine/forkable.h
- src/core/lib/event_engine/grpc_polled_fd.h
- src/core/lib/event_engine/handle_containers.h
- src/core/lib/event_engine/memory_allocator_factory.h
- src/core/lib/event_engine/nameser.h
- src/core/lib/event_engine/poller.h
- src/core/lib/event_engine/posix.h
- src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h
- src/core/lib/event_engine/posix_engine/ev_poll_posix.h
- src/core/lib/event_engine/posix_engine/event_poller.h
- src/core/lib/event_engine/posix_engine/event_poller_posix_default.h
- src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h
- src/core/lib/event_engine/posix_engine/internal_errqueue.h
- src/core/lib/event_engine/posix_engine/lockfree_event.h
- src/core/lib/event_engine/posix_engine/native_dns_resolver.h
- src/core/lib/event_engine/posix_engine/posix_endpoint.h
- src/core/lib/event_engine/posix_engine/posix_engine.h
- src/core/lib/event_engine/posix_engine/posix_engine_closure.h
- src/core/lib/event_engine/posix_engine/posix_engine_listener.h
- src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h
- src/core/lib/event_engine/posix_engine/tcp_socket_utils.h
- src/core/lib/event_engine/posix_engine/timer.h
- src/core/lib/event_engine/posix_engine/timer_heap.h
- src/core/lib/event_engine/posix_engine/timer_manager.h
- src/core/lib/event_engine/posix_engine/traced_buffer_list.h
- src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h
- src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h
- src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h
- src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h
- src/core/lib/event_engine/ref_counted_dns_resolver_interface.h
- src/core/lib/event_engine/resolved_address_internal.h
- src/core/lib/event_engine/shim.h
- src/core/lib/event_engine/tcp_socket_utils.h
- src/core/lib/event_engine/thread_pool/thread_count.h
- src/core/lib/event_engine/thread_pool/thread_pool.h
- src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h
- src/core/lib/event_engine/thready_event_engine/thready_event_engine.h
- src/core/lib/event_engine/time_util.h
- src/core/lib/event_engine/trace.h
- src/core/lib/event_engine/utils.h
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.h
- src/core/lib/event_engine/windows/iocp.h
- src/core/lib/event_engine/windows/win_socket.h
- src/core/lib/event_engine/windows/windows_endpoint.h
- src/core/lib/event_engine/windows/windows_engine.h
- src/core/lib/event_engine/windows/windows_listener.h
- src/core/lib/event_engine/work_queue/basic_work_queue.h
- src/core/lib/event_engine/work_queue/work_queue.h
- src/core/lib/experiments/config.h
- src/core/lib/experiments/experiments.h
- src/core/lib/gpr/spinlock.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/chunked_vector.h
- src/core/lib/gprpp/cpp_impl_of.h
- src/core/lib/gprpp/dual_ref_counted.h
- src/core/lib/gprpp/if_list.h
- src/core/lib/gprpp/load_file.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/match.h
- src/core/lib/gprpp/notification.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/overload.h
- src/core/lib/gprpp/packed_table.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/ref_counted_string.h
- src/core/lib/gprpp/sorted_pack.h
- src/core/lib/gprpp/status_helper.h
- src/core/lib/gprpp/table.h
- src/core/lib/gprpp/time.h
- src/core/lib/gprpp/time_averaged_stats.h
- src/core/lib/gprpp/type_list.h
- src/core/lib/gprpp/unique_type_name.h
- src/core/lib/gprpp/validation_errors.h
- src/core/lib/gprpp/work_serializer.h
- src/core/lib/handshaker/proxy_mapper.h
- src/core/lib/handshaker/proxy_mapper_registry.h
- src/core/lib/iomgr/block_annotate.h
- src/core/lib/iomgr/buffer_list.h
- src/core/lib/iomgr/call_combiner.h
- src/core/lib/iomgr/cfstream_handle.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/dynamic_annotations.h
- src/core/lib/iomgr/endpoint.h
- src/core/lib/iomgr/endpoint_cfstream.h
- src/core/lib/iomgr/endpoint_pair.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/error_cfstream.h
- src/core/lib/iomgr/ev_apple.h
- src/core/lib/iomgr/ev_epoll1_linux.h
- src/core/lib/iomgr/ev_poll_posix.h
- src/core/lib/iomgr/ev_posix.h
- src/core/lib/iomgr/event_engine_shims/closure.h
- src/core/lib/iomgr/event_engine_shims/endpoint.h
- src/core/lib/iomgr/event_engine_shims/tcp_client.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/gethostname.h
- src/core/lib/iomgr/grpc_if_nametoindex.h
- src/core/lib/iomgr/internal_errqueue.h
- src/core/lib/iomgr/iocp_windows.h
- src/core/lib/iomgr/iomgr.h
- src/core/lib/iomgr/iomgr_fwd.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/iomgr/load_file.h
- src/core/lib/iomgr/lockfree_event.h
- src/core/lib/iomgr/nameser.h
- src/core/lib/iomgr/polling_entity.h
- src/core/lib/iomgr/pollset.h
- src/core/lib/iomgr/pollset_set.h
- src/core/lib/iomgr/pollset_set_windows.h
- src/core/lib/iomgr/pollset_windows.h
- src/core/lib/iomgr/port.h
- src/core/lib/iomgr/python_util.h
- src/core/lib/iomgr/resolve_address.h
- src/core/lib/iomgr/resolve_address_impl.h
- src/core/lib/iomgr/resolve_address_posix.h
- src/core/lib/iomgr/resolve_address_windows.h
- src/core/lib/iomgr/resolved_address.h
- src/core/lib/iomgr/sockaddr.h
- src/core/lib/iomgr/sockaddr_posix.h
- src/core/lib/iomgr/sockaddr_windows.h
- src/core/lib/iomgr/socket_factory_posix.h
- src/core/lib/iomgr/socket_mutator.h
- src/core/lib/iomgr/socket_utils.h
- src/core/lib/iomgr/socket_utils_posix.h
- src/core/lib/iomgr/socket_windows.h
- src/core/lib/iomgr/systemd_utils.h
- src/core/lib/iomgr/tcp_client.h
- src/core/lib/iomgr/tcp_client_posix.h
- src/core/lib/iomgr/tcp_posix.h
- src/core/lib/iomgr/tcp_server.h
- src/core/lib/iomgr/tcp_server_utils_posix.h
- src/core/lib/iomgr/tcp_windows.h
- src/core/lib/iomgr/timer.h
- src/core/lib/iomgr/timer_generic.h
- src/core/lib/iomgr/timer_heap.h
- src/core/lib/iomgr/timer_manager.h
- src/core/lib/iomgr/unix_sockets_posix.h
- src/core/lib/iomgr/vsock.h
- src/core/lib/iomgr/wakeup_fd_pipe.h
- src/core/lib/iomgr/wakeup_fd_posix.h
- src/core/lib/json/json.h
- src/core/lib/json/json_args.h
- src/core/lib/json/json_writer.h
- src/core/lib/load_balancing/lb_policy.h
- src/core/lib/load_balancing/lb_policy_factory.h
- src/core/lib/load_balancing/lb_policy_registry.h
- src/core/lib/load_balancing/subchannel_interface.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/all_ok.h
- src/core/lib/promise/arena_promise.h
- src/core/lib/promise/cancel_callback.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/join_state.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- 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/for_each.h
- src/core/lib/promise/if.h
- src/core/lib/promise/interceptor_list.h
- src/core/lib/promise/latch.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/party.h
- src/core/lib/promise/pipe.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/promise.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/promise/status_flag.h
- src/core/lib/promise/trace.h
- src/core/lib/promise/try_join.h
- src/core/lib/promise/try_seq.h
- src/core/lib/resolver/endpoint_addresses.h
- src/core/lib/resolver/resolver.h
- src/core/lib/resolver/resolver_factory.h
- src/core/lib/resolver/resolver_registry.h
- src/core/lib/resolver/server_address.h
- src/core/lib/resource_quota/api.h
- src/core/lib/resource_quota/arena.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/periodic_update.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/security/certificate_provider/certificate_provider_factory.h
- src/core/lib/security/certificate_provider/certificate_provider_registry.h
- src/core/lib/security/credentials/alts/check_gcp_environment.h
- src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
- src/core/lib/security/credentials/channel_creds_registry.h
- src/core/lib/service_config/service_config.h
- src/core/lib/service_config/service_config_call_data.h
- src/core/lib/service_config/service_config_parser.h
- src/core/lib/slice/b64.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_buffer.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/surface/api_trace.h
- src/core/lib/surface/builtins.h
- src/core/lib/surface/call.h
- src/core/lib/surface/call_test_only.h
- src/core/lib/surface/call_trace.h
- src/core/lib/surface/channel.h
- src/core/lib/surface/channel_init.h
- src/core/lib/surface/channel_stack_type.h
- src/core/lib/surface/completion_queue.h
- src/core/lib/surface/completion_queue_factory.h
- src/core/lib/surface/event_string.h
- src/core/lib/surface/init.h
- src/core/lib/surface/init_internally.h
- src/core/lib/surface/lame_client.h
- src/core/lib/surface/server.h
- src/core/lib/surface/validate_metadata.h
- src/core/lib/surface/wait_for_cq_end_op.h
- src/core/lib/transport/batch_builder.h
- src/core/lib/transport/connectivity_state.h
- src/core/lib/transport/custom_metadata.h
- src/core/lib/transport/error_utils.h
- src/core/lib/transport/handshaker_factory.h
- src/core/lib/transport/handshaker_registry.h
- src/core/lib/transport/http2_errors.h
- src/core/lib/transport/metadata_batch.h
- src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/simple_slice_based_metadata.h
- src/core/lib/transport/status_conversion.h
- src/core/lib/transport/timeout_encoding.h
- src/core/lib/transport/transport.h
- src/core/lib/transport/transport_fwd.h
- src/core/lib/uri/uri_parser.h
- src/core/tsi/alts/handshaker/transport_security_common_api.h
- third_party/upb/upb/base/internal/log2.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/hash/common.h
- third_party/upb/upb/hash/int_table.h
- third_party/upb/upb/hash/str_table.h
- third_party/upb/upb/message/accessors.h
- third_party/upb/upb/message/array.h
- third_party/upb/upb/message/internal/accessors.h
- third_party/upb/upb/message/internal/array.h
- third_party/upb/upb/message/internal/extension.h
- third_party/upb/upb/message/internal/map.h
- third_party/upb/upb/message/internal/map_entry.h
- third_party/upb/upb/message/internal/map_sorter.h
- third_party/upb/upb/message/internal/message.h
- third_party/upb/upb/message/internal/types.h
- third_party/upb/upb/message/map.h
- third_party/upb/upb/message/map_gencode_util.h
- third_party/upb/upb/message/message.h
- third_party/upb/upb/message/tagged_ptr.h
- third_party/upb/upb/message/types.h
- third_party/upb/upb/message/value.h
- third_party/upb/upb/mini_descriptor/build_enum.h
- third_party/upb/upb/mini_descriptor/decode.h
- third_party/upb/upb/mini_descriptor/internal/base92.h
- third_party/upb/upb/mini_descriptor/internal/decoder.h
- third_party/upb/upb/mini_descriptor/internal/encode.h
- third_party/upb/upb/mini_descriptor/internal/encode.hpp
- third_party/upb/upb/mini_descriptor/internal/modifiers.h
- third_party/upb/upb/mini_descriptor/internal/wire_constants.h
- third_party/upb/upb/mini_descriptor/link.h
- third_party/upb/upb/mini_table/enum.h
- third_party/upb/upb/mini_table/extension.h
- third_party/upb/upb/mini_table/extension_registry.h
- third_party/upb/upb/mini_table/field.h
- third_party/upb/upb/mini_table/file.h
- third_party/upb/upb/mini_table/internal/enum.h
- third_party/upb/upb/mini_table/internal/extension.h
- third_party/upb/upb/mini_table/internal/field.h
- third_party/upb/upb/mini_table/internal/file.h
- third_party/upb/upb/mini_table/internal/message.h
- third_party/upb/upb/mini_table/internal/sub.h
- third_party/upb/upb/mini_table/message.h
- third_party/upb/upb/mini_table/sub.h
- third_party/upb/upb/wire/decode.h
- third_party/upb/upb/wire/decode_fast.h
- third_party/upb/upb/wire/encode.h
- third_party/upb/upb/wire/eps_copy_input_stream.h
- third_party/upb/upb/wire/internal/constants.h
- third_party/upb/upb/wire/internal/decode.h
- third_party/upb/upb/wire/internal/swap.h
- third_party/upb/upb/wire/reader.h
- third_party/upb/upb/wire/types.h
src:
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/ext/transport/chttp2/transport/bin_encoder.cc
- src/core/ext/transport/chttp2/transport/decode_huff.cc
- src/core/ext/transport/chttp2/transport/hpack_encoder.cc
- src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
- src/core/ext/transport/chttp2/transport/hpack_parse_result.cc
- src/core/ext/transport/chttp2/transport/hpack_parser.cc
- src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
- src/core/ext/transport/chttp2/transport/http_trace.cc
- src/core/ext/transport/chttp2/transport/huffsyms.cc
- src/core/ext/transport/chttp2/transport/varint.cc
- src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c
- src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c
- src/core/ext/upb-gen/google/rpc/status.upb_minitable.c
- src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c
- src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c
- src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c
- src/core/lib/address_utils/parse_address.cc
- src/core/lib/address_utils/sockaddr_utils.cc
- src/core/lib/backoff/backoff.cc
- src/core/lib/backoff/random_early_detection.cc
- src/core/lib/channel/call_tracer.cc
- src/core/lib/channel/channel_args.cc
- src/core/lib/channel/channel_args_preconditioning.cc
- src/core/lib/channel/channel_stack.cc
- src/core/lib/channel/channel_stack_builder.cc
- src/core/lib/channel/channel_stack_builder_impl.cc
- src/core/lib/channel/channel_stack_trace.cc
- src/core/lib/channel/channel_trace.cc
- src/core/lib/channel/channelz.cc
- src/core/lib/channel/channelz_registry.cc
- src/core/lib/channel/connected_channel.cc
- src/core/lib/channel/promise_based_filter.cc
- src/core/lib/channel/server_call_tracer_filter.cc
- src/core/lib/channel/status_util.cc
- src/core/lib/compression/compression.cc
- src/core/lib/compression/compression_internal.cc
- src/core/lib/compression/message_compress.cc
- src/core/lib/config/core_configuration.cc
- src/core/lib/debug/event_log.cc
- src/core/lib/debug/histogram_view.cc
- src/core/lib/debug/stats.cc
- src/core/lib/debug/stats_data.cc
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/ares_resolver.cc
- src/core/lib/event_engine/cf_engine/cf_engine.cc
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
- src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
- src/core/lib/event_engine/event_engine.cc
- src/core/lib/event_engine/forkable.cc
- src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
- src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
- src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc
- src/core/lib/event_engine/posix_engine/internal_errqueue.cc
- src/core/lib/event_engine/posix_engine/lockfree_event.cc
- src/core/lib/event_engine/posix_engine/native_dns_resolver.cc
- src/core/lib/event_engine/posix_engine/posix_endpoint.cc
- src/core/lib/event_engine/posix_engine/posix_engine.cc
- src/core/lib/event_engine/posix_engine/posix_engine_listener.cc
- src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc
- src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc
- src/core/lib/event_engine/posix_engine/timer.cc
- src/core/lib/event_engine/posix_engine/timer_heap.cc
- src/core/lib/event_engine/posix_engine/timer_manager.cc
- src/core/lib/event_engine/posix_engine/traced_buffer_list.cc
- src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc
- src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc
- src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc
- src/core/lib/event_engine/resolved_address.cc
- src/core/lib/event_engine/shim.cc
- src/core/lib/event_engine/slice.cc
- src/core/lib/event_engine/slice_buffer.cc
- src/core/lib/event_engine/tcp_socket_utils.cc
- src/core/lib/event_engine/thread_pool/thread_count.cc
- src/core/lib/event_engine/thread_pool/thread_pool_factory.cc
- src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc
- src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc
- src/core/lib/event_engine/time_util.cc
- src/core/lib/event_engine/trace.cc
- src/core/lib/event_engine/utils.cc
- src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc
- src/core/lib/event_engine/windows/iocp.cc
- src/core/lib/event_engine/windows/win_socket.cc
- src/core/lib/event_engine/windows/windows_endpoint.cc
- src/core/lib/event_engine/windows/windows_engine.cc
- src/core/lib/event_engine/windows/windows_listener.cc
- src/core/lib/event_engine/work_queue/basic_work_queue.cc
- src/core/lib/experiments/config.cc
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/load_file.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/ref_counted_string.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/gprpp/time_averaged_stats.cc
- src/core/lib/gprpp/validation_errors.cc
- src/core/lib/gprpp/work_serializer.cc
- src/core/lib/handshaker/proxy_mapper_registry.cc
- src/core/lib/iomgr/buffer_list.cc
- src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/cfstream_handle.cc
- src/core/lib/iomgr/closure.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/dualstack_socket_posix.cc
- src/core/lib/iomgr/endpoint.cc
- src/core/lib/iomgr/endpoint_cfstream.cc
- src/core/lib/iomgr/endpoint_pair_posix.cc
- src/core/lib/iomgr/endpoint_pair_windows.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/error_cfstream.cc
- src/core/lib/iomgr/ev_apple.cc
- src/core/lib/iomgr/ev_epoll1_linux.cc
- src/core/lib/iomgr/ev_poll_posix.cc
- src/core/lib/iomgr/ev_posix.cc
- src/core/lib/iomgr/ev_windows.cc
- src/core/lib/iomgr/event_engine_shims/closure.cc
- src/core/lib/iomgr/event_engine_shims/endpoint.cc
- src/core/lib/iomgr/event_engine_shims/tcp_client.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/fork_posix.cc
- src/core/lib/iomgr/fork_windows.cc
- src/core/lib/iomgr/gethostname_fallback.cc
- src/core/lib/iomgr/gethostname_host_name_max.cc
- src/core/lib/iomgr/gethostname_sysconf.cc
- src/core/lib/iomgr/grpc_if_nametoindex_posix.cc
- src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc
- src/core/lib/iomgr/internal_errqueue.cc
- src/core/lib/iomgr/iocp_windows.cc
- src/core/lib/iomgr/iomgr.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/iomgr/iomgr_posix.cc
- src/core/lib/iomgr/iomgr_posix_cfstream.cc
- src/core/lib/iomgr/iomgr_windows.cc
- src/core/lib/iomgr/load_file.cc
- src/core/lib/iomgr/lockfree_event.cc
- src/core/lib/iomgr/polling_entity.cc
- src/core/lib/iomgr/pollset.cc
- src/core/lib/iomgr/pollset_set.cc
- src/core/lib/iomgr/pollset_set_windows.cc
- src/core/lib/iomgr/pollset_windows.cc
- src/core/lib/iomgr/resolve_address.cc
- src/core/lib/iomgr/resolve_address_posix.cc
- src/core/lib/iomgr/resolve_address_windows.cc
- src/core/lib/iomgr/sockaddr_utils_posix.cc
- src/core/lib/iomgr/socket_factory_posix.cc
- src/core/lib/iomgr/socket_mutator.cc
- src/core/lib/iomgr/socket_utils_common_posix.cc
- src/core/lib/iomgr/socket_utils_linux.cc
- src/core/lib/iomgr/socket_utils_posix.cc
- src/core/lib/iomgr/socket_utils_windows.cc
- src/core/lib/iomgr/socket_windows.cc
- src/core/lib/iomgr/systemd_utils.cc
- src/core/lib/iomgr/tcp_client.cc
- src/core/lib/iomgr/tcp_client_cfstream.cc
- src/core/lib/iomgr/tcp_client_posix.cc
- src/core/lib/iomgr/tcp_client_windows.cc
- src/core/lib/iomgr/tcp_posix.cc
- src/core/lib/iomgr/tcp_server.cc
- src/core/lib/iomgr/tcp_server_posix.cc
- src/core/lib/iomgr/tcp_server_utils_posix_common.cc
- src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc
- src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc
- src/core/lib/iomgr/tcp_server_windows.cc
- src/core/lib/iomgr/tcp_windows.cc
- src/core/lib/iomgr/timer.cc
- src/core/lib/iomgr/timer_generic.cc
- src/core/lib/iomgr/timer_heap.cc
- src/core/lib/iomgr/timer_manager.cc
- src/core/lib/iomgr/unix_sockets_posix.cc
- src/core/lib/iomgr/unix_sockets_posix_noop.cc
- src/core/lib/iomgr/vsock.cc
- src/core/lib/iomgr/wakeup_fd_eventfd.cc
- src/core/lib/iomgr/wakeup_fd_nospecial.cc
- src/core/lib/iomgr/wakeup_fd_pipe.cc
- src/core/lib/iomgr/wakeup_fd_posix.cc
- src/core/lib/json/json_writer.cc
- src/core/lib/load_balancing/lb_policy.cc
- src/core/lib/load_balancing/lb_policy_registry.cc
- src/core/lib/promise/activity.cc
- src/core/lib/promise/party.cc
- src/core/lib/promise/trace.cc
- src/core/lib/resolver/endpoint_addresses.cc
- src/core/lib/resolver/resolver.cc
- src/core/lib/resolver/resolver_registry.cc
- src/core/lib/resource_quota/api.cc
- src/core/lib/resource_quota/arena.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/periodic_update.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/security/certificate_provider/certificate_provider_registry.cc
- src/core/lib/security/credentials/alts/check_gcp_environment.cc
- src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
- src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc
- src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc
- src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
- src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc
- src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
- src/core/lib/service_config/service_config_parser.cc
- src/core/lib/slice/b64.cc
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/surface/api_trace.cc
- src/core/lib/surface/builtins.cc
- src/core/lib/surface/byte_buffer.cc
- src/core/lib/surface/byte_buffer_reader.cc
- src/core/lib/surface/call.cc
- src/core/lib/surface/call_details.cc
- src/core/lib/surface/call_log_batch.cc
- src/core/lib/surface/call_trace.cc
- src/core/lib/surface/channel.cc
- src/core/lib/surface/channel_init.cc
- src/core/lib/surface/channel_ping.cc
- src/core/lib/surface/channel_stack_type.cc
- src/core/lib/surface/completion_queue.cc
- src/core/lib/surface/completion_queue_factory.cc
- src/core/lib/surface/event_string.cc
- src/core/lib/surface/init_internally.cc
- src/core/lib/surface/lame_client.cc
- src/core/lib/surface/metadata_array.cc
- src/core/lib/surface/server.cc
- src/core/lib/surface/validate_metadata.cc
- src/core/lib/surface/version.cc
- src/core/lib/transport/batch_builder.cc
- src/core/lib/transport/connectivity_state.cc
- src/core/lib/transport/error_utils.cc
- src/core/lib/transport/handshaker_registry.cc
- src/core/lib/transport/metadata_batch.cc
- src/core/lib/transport/parsed_metadata.cc
- src/core/lib/transport/status_conversion.cc
- src/core/lib/transport/timeout_encoding.cc
- src/core/lib/transport/transport.cc
- src/core/lib/transport/transport_op_string.cc
- src/core/lib/uri/uri_parser.cc
- src/core/tsi/alts/handshaker/transport_security_common_api.cc
- test/core/transport/chaotic_good/frame_test.cc
- third_party/upb/upb/hash/common.c
- third_party/upb/upb/message/accessors.c
- third_party/upb/upb/message/array.c
- third_party/upb/upb/message/map.c
- third_party/upb/upb/message/map_sorter.c
- third_party/upb/upb/message/message.c
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
- third_party/upb/upb/mini_descriptor/internal/base92.c
- third_party/upb/upb/mini_descriptor/internal/encode.c
- third_party/upb/upb/mini_descriptor/link.c
- third_party/upb/upb/mini_table/extension_registry.c
- third_party/upb/upb/mini_table/internal/message.c
- third_party/upb/upb/mini_table/message.c
- third_party/upb/upb/wire/decode.c
- third_party/upb/upb/wire/decode_fast.c
- third_party/upb/upb/wire/encode.c
- third_party/upb/upb/wire/eps_copy_input_stream.c
- third_party/upb/upb/wire/reader.c
deps:
- gtest
- upb
- utf8_range_lib
- z
- absl/cleanup:cleanup
- absl/container:flat_hash_map
- absl/container:inlined_vector
- absl/functional:function_ref
- absl/hash:hash
- absl/meta:type_traits
- absl/random:bit_gen_ref
- absl/random:distributions
- absl/status:statusor
- absl/types:span
- absl/utility:utility
- cares
- gpr
- name: test_core_transport_chttp2_frame_test
gtest: true
build: test
language: c++
headers:
- src/core/ext/transport/chttp2/transport/frame.h
- src/core/lib/debug/trace.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_buffer.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/transport/http2_errors.h
src:
- src/core/ext/transport/chttp2/transport/frame.cc
- src/core/lib/debug/trace.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- test/core/transport/chttp2/frame_test.cc
deps:
- gtest
- absl/hash:hash
- absl/status:statusor
- absl/types:span
- gpr
uses_polling: false
- name: test_cpp_client_credentials_test
gtest: true
build: test

4
config.m4 generated

@ -544,7 +544,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \
src/core/lib/event_engine/posix_engine/internal_errqueue.cc \
src/core/lib/event_engine/posix_engine/lockfree_event.cc \
src/core/lib/event_engine/posix_engine/native_dns_resolver.cc \
src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \
src/core/lib/event_engine/posix_engine/posix_endpoint.cc \
src/core/lib/event_engine/posix_engine/posix_engine.cc \
src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \
@ -572,6 +572,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/event_engine/utils.cc \
src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc \
src/core/lib/event_engine/windows/iocp.cc \
src/core/lib/event_engine/windows/native_windows_dns_resolver.cc \
src/core/lib/event_engine/windows/win_socket.cc \
src/core/lib/event_engine/windows/windows_endpoint.cc \
src/core/lib/event_engine/windows/windows_engine.cc \
@ -839,7 +840,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/transport/http_connect_handshaker.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/parsed_metadata.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/tcp_connect_handshaker.cc \
src/core/lib/transport/timeout_encoding.cc \

4
config.w32 generated

@ -509,7 +509,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\event_engine\\posix_engine\\event_poller_posix_default.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\internal_errqueue.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\lockfree_event.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\native_dns_resolver.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\native_posix_dns_resolver.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\posix_endpoint.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\posix_engine.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\posix_engine_listener.cc " +
@ -537,6 +537,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\event_engine\\utils.cc " +
"src\\core\\lib\\event_engine\\windows\\grpc_polled_fd_windows.cc " +
"src\\core\\lib\\event_engine\\windows\\iocp.cc " +
"src\\core\\lib\\event_engine\\windows\\native_windows_dns_resolver.cc " +
"src\\core\\lib\\event_engine\\windows\\win_socket.cc " +
"src\\core\\lib\\event_engine\\windows\\windows_endpoint.cc " +
"src\\core\\lib\\event_engine\\windows\\windows_engine.cc " +
@ -804,7 +805,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\transport\\http_connect_handshaker.cc " +
"src\\core\\lib\\transport\\metadata_batch.cc " +
"src\\core\\lib\\transport\\parsed_metadata.cc " +
"src\\core\\lib\\transport\\pid_controller.cc " +
"src\\core\\lib\\transport\\status_conversion.cc " +
"src\\core\\lib\\transport\\tcp_connect_handshaker.cc " +
"src\\core\\lib\\transport\\timeout_encoding.cc " +

@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
# Protobuf Python Version: 4.25.0
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
@ -13,18 +14,18 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\xe4\x01\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x12K\n\x13SayHelloStreamReply\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x30\x01\x12L\n\x12SayHelloBidiStream\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', globals())
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'
_HELLOREQUEST._serialized_start=32
_HELLOREQUEST._serialized_end=60
_HELLOREPLY._serialized_start=62
_HELLOREPLY._serialized_end=91
_GREETER._serialized_start=93
_GREETER._serialized_end=166
_globals['DESCRIPTOR']._options = None
_globals['DESCRIPTOR']._serialized_options = b'\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'
_globals['_HELLOREQUEST']._serialized_start=32
_globals['_HELLOREQUEST']._serialized_end=60
_globals['_HELLOREPLY']._serialized_start=62
_globals['_HELLOREPLY']._serialized_end=91
_globals['_GREETER']._serialized_start=94
_globals['_GREETER']._serialized_end=322
# @@protoc_insertion_point(module_scope)

@ -4,14 +4,14 @@ from typing import ClassVar as _ClassVar, Optional as _Optional
DESCRIPTOR: _descriptor.FileDescriptor
class HelloReply(_message.Message):
__slots__ = ["message"]
MESSAGE_FIELD_NUMBER: _ClassVar[int]
message: str
def __init__(self, message: _Optional[str] = ...) -> None: ...
class HelloRequest(_message.Message):
__slots__ = ["name"]
__slots__ = ("name",)
NAME_FIELD_NUMBER: _ClassVar[int]
name: str
def __init__(self, name: _Optional[str] = ...) -> None: ...
class HelloReply(_message.Message):
__slots__ = ("message",)
MESSAGE_FIELD_NUMBER: _ClassVar[int]
message: str
def __init__(self, message: _Optional[str] = ...) -> None: ...

@ -19,7 +19,17 @@ class GreeterStub(object):
'/helloworld.Greeter/SayHello',
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
)
_registered_method=True)
self.SayHelloStreamReply = channel.unary_stream(
'/helloworld.Greeter/SayHelloStreamReply',
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
_registered_method=True)
self.SayHelloBidiStream = channel.stream_stream(
'/helloworld.Greeter/SayHelloBidiStream',
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
_registered_method=True)
class GreeterServicer(object):
@ -33,6 +43,18 @@ class GreeterServicer(object):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SayHelloStreamReply(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SayHelloBidiStream(self, request_iterator, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_GreeterServicer_to_server(servicer, server):
rpc_method_handlers = {
@ -41,6 +63,16 @@ def add_GreeterServicer_to_server(servicer, server):
request_deserializer=helloworld__pb2.HelloRequest.FromString,
response_serializer=helloworld__pb2.HelloReply.SerializeToString,
),
'SayHelloStreamReply': grpc.unary_stream_rpc_method_handler(
servicer.SayHelloStreamReply,
request_deserializer=helloworld__pb2.HelloRequest.FromString,
response_serializer=helloworld__pb2.HelloReply.SerializeToString,
),
'SayHelloBidiStream': grpc.stream_stream_rpc_method_handler(
servicer.SayHelloBidiStream,
request_deserializer=helloworld__pb2.HelloRequest.FromString,
response_serializer=helloworld__pb2.HelloReply.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'helloworld.Greeter', rpc_method_handlers)
@ -63,8 +95,72 @@ class Greeter(object):
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/helloworld.Greeter/SayHello',
return grpc.experimental.unary_unary(
request,
target,
'/helloworld.Greeter/SayHello',
helloworld__pb2.HelloRequest.SerializeToString,
helloworld__pb2.HelloReply.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def SayHelloStreamReply(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(
request,
target,
'/helloworld.Greeter/SayHelloStreamReply',
helloworld__pb2.HelloRequest.SerializeToString,
helloworld__pb2.HelloReply.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def SayHelloBidiStream(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(
request_iterator,
target,
'/helloworld.Greeter/SayHelloBidiStream',
helloworld__pb2.HelloRequest.SerializeToString,
helloworld__pb2.HelloReply.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)

8
gRPC-C++.podspec generated

@ -958,7 +958,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h',
'src/core/lib/event_engine/posix_engine/internal_errqueue.h',
'src/core/lib/event_engine/posix_engine/lockfree_event.h',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/posix_endpoint.h',
'src/core/lib/event_engine/posix_engine/posix_engine.h',
'src/core/lib/event_engine/posix_engine/posix_engine_closure.h',
@ -987,6 +987,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/utils.h',
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h',
'src/core/lib/event_engine/windows/iocp.h',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.h',
'src/core/lib/event_engine/windows/win_socket.h',
'src/core/lib/event_engine/windows/windows_endpoint.h',
'src/core/lib/event_engine/windows/windows_engine.h',
@ -1273,7 +1274,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/tcp_connect_handshaker.h',
@ -2203,7 +2203,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h',
'src/core/lib/event_engine/posix_engine/internal_errqueue.h',
'src/core/lib/event_engine/posix_engine/lockfree_event.h',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/posix_endpoint.h',
'src/core/lib/event_engine/posix_engine/posix_engine.h',
'src/core/lib/event_engine/posix_engine/posix_engine_closure.h',
@ -2232,6 +2232,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/utils.h',
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h',
'src/core/lib/event_engine/windows/iocp.h',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.h',
'src/core/lib/event_engine/windows/win_socket.h',
'src/core/lib/event_engine/windows/windows_endpoint.h',
'src/core/lib/event_engine/windows/windows_engine.h',
@ -2518,7 +2519,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/tcp_connect_handshaker.h',

12
gRPC-Core.podspec generated

@ -1392,8 +1392,8 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/posix_engine/internal_errqueue.h',
'src/core/lib/event_engine/posix_engine/lockfree_event.cc',
'src/core/lib/event_engine/posix_engine/lockfree_event.h',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/posix_endpoint.cc',
'src/core/lib/event_engine/posix_engine/posix_endpoint.h',
'src/core/lib/event_engine/posix_engine/posix_engine.cc',
@ -1449,6 +1449,8 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h',
'src/core/lib/event_engine/windows/iocp.cc',
'src/core/lib/event_engine/windows/iocp.h',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.h',
'src/core/lib/event_engine/windows/win_socket.cc',
'src/core/lib/event_engine/windows/win_socket.h',
'src/core/lib/event_engine/windows/windows_endpoint.cc',
@ -2002,8 +2004,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.cc',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_conversion.h',
@ -2972,7 +2972,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h',
'src/core/lib/event_engine/posix_engine/internal_errqueue.h',
'src/core/lib/event_engine/posix_engine/lockfree_event.h',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h',
'src/core/lib/event_engine/posix_engine/posix_endpoint.h',
'src/core/lib/event_engine/posix_engine/posix_engine.h',
'src/core/lib/event_engine/posix_engine/posix_engine_closure.h',
@ -3001,6 +3001,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/utils.h',
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.h',
'src/core/lib/event_engine/windows/iocp.h',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.h',
'src/core/lib/event_engine/windows/win_socket.h',
'src/core/lib/event_engine/windows/windows_endpoint.h',
'src/core/lib/event_engine/windows/windows_engine.h',
@ -3287,7 +3288,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/tcp_connect_handshaker.h',

8
grpc.gemspec generated

@ -1295,8 +1295,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/event_engine/posix_engine/internal_errqueue.h )
s.files += %w( src/core/lib/event_engine/posix_engine/lockfree_event.cc )
s.files += %w( src/core/lib/event_engine/posix_engine/lockfree_event.h )
s.files += %w( src/core/lib/event_engine/posix_engine/native_dns_resolver.cc )
s.files += %w( src/core/lib/event_engine/posix_engine/native_dns_resolver.h )
s.files += %w( src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc )
s.files += %w( src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h )
s.files += %w( src/core/lib/event_engine/posix_engine/posix_endpoint.cc )
s.files += %w( src/core/lib/event_engine/posix_engine/posix_endpoint.h )
s.files += %w( src/core/lib/event_engine/posix_engine/posix_engine.cc )
@ -1352,6 +1352,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/event_engine/windows/grpc_polled_fd_windows.h )
s.files += %w( src/core/lib/event_engine/windows/iocp.cc )
s.files += %w( src/core/lib/event_engine/windows/iocp.h )
s.files += %w( src/core/lib/event_engine/windows/native_windows_dns_resolver.cc )
s.files += %w( src/core/lib/event_engine/windows/native_windows_dns_resolver.h )
s.files += %w( src/core/lib/event_engine/windows/win_socket.cc )
s.files += %w( src/core/lib/event_engine/windows/win_socket.h )
s.files += %w( src/core/lib/event_engine/windows/windows_endpoint.cc )
@ -1905,8 +1907,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/metadata_compression_traits.h )
s.files += %w( src/core/lib/transport/parsed_metadata.cc )
s.files += %w( src/core/lib/transport/parsed_metadata.h )
s.files += %w( src/core/lib/transport/pid_controller.cc )
s.files += %w( src/core/lib/transport/pid_controller.h )
s.files += %w( src/core/lib/transport/simple_slice_based_metadata.h )
s.files += %w( src/core/lib/transport/status_conversion.cc )
s.files += %w( src/core/lib/transport/status_conversion.h )

11
grpc.gyp generated

@ -774,7 +774,7 @@
'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc',
'src/core/lib/event_engine/posix_engine/internal_errqueue.cc',
'src/core/lib/event_engine/posix_engine/lockfree_event.cc',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/posix_endpoint.cc',
'src/core/lib/event_engine/posix_engine/posix_engine.cc',
'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc',
@ -801,6 +801,7 @@
'src/core/lib/event_engine/utils.cc',
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc',
'src/core/lib/event_engine/windows/iocp.cc',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc',
'src/core/lib/event_engine/windows/win_socket.cc',
'src/core/lib/event_engine/windows/windows_endpoint.cc',
'src/core/lib/event_engine/windows/windows_engine.cc',
@ -1026,7 +1027,6 @@
'src/core/lib/transport/http_connect_handshaker.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/parsed_metadata.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/tcp_connect_handshaker.cc',
'src/core/lib/transport/timeout_encoding.cc',
@ -1297,7 +1297,7 @@
'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc',
'src/core/lib/event_engine/posix_engine/internal_errqueue.cc',
'src/core/lib/event_engine/posix_engine/lockfree_event.cc',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/posix_endpoint.cc',
'src/core/lib/event_engine/posix_engine/posix_engine.cc',
'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc',
@ -1324,6 +1324,7 @@
'src/core/lib/event_engine/utils.cc',
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc',
'src/core/lib/event_engine/windows/iocp.cc',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc',
'src/core/lib/event_engine/windows/win_socket.cc',
'src/core/lib/event_engine/windows/windows_endpoint.cc',
'src/core/lib/event_engine/windows/windows_engine.cc',
@ -1510,7 +1511,6 @@
'src/core/lib/transport/http_connect_handshaker.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/parsed_metadata.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/tcp_connect_handshaker.cc',
'src/core/lib/transport/timeout_encoding.cc',
@ -2077,7 +2077,7 @@
'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc',
'src/core/lib/event_engine/posix_engine/internal_errqueue.cc',
'src/core/lib/event_engine/posix_engine/lockfree_event.cc',
'src/core/lib/event_engine/posix_engine/native_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc',
'src/core/lib/event_engine/posix_engine/posix_endpoint.cc',
'src/core/lib/event_engine/posix_engine/posix_engine.cc',
'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc',
@ -2104,6 +2104,7 @@
'src/core/lib/event_engine/utils.cc',
'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc',
'src/core/lib/event_engine/windows/iocp.cc',
'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc',
'src/core/lib/event_engine/windows/win_socket.cc',
'src/core/lib/event_engine/windows/windows_endpoint.cc',
'src/core/lib/event_engine/windows/windows_engine.cc',

@ -60,6 +60,18 @@ Result& SliceCast(T& value, SliceCastable<Result, T> = {}) {
return reinterpret_cast<Result&>(value);
}
// Cast to `Result&&` from `T&&` without any runtime checks.
// This is only valid if `sizeof(Result) == sizeof(T)`, and if `Result`, `T` are
// opted in as compatible via `SliceCastable`.
template <typename Result, typename T>
Result&& SliceCast(T&& value, SliceCastable<Result, T> = {}) {
// Insist upon sizes being equal to catch mismatches.
// We assume if sizes are opted in and sizes are equal then yes, these two
// types are expected to be layout compatible and actually appear to be.
static_assert(sizeof(Result) == sizeof(T), "size mismatch");
return reinterpret_cast<Result&&>(value);
}
} // namespace internal
} // namespace experimental
} // namespace grpc_event_engine

@ -169,6 +169,11 @@ struct CopyConstructors {
return Out(grpc_slice_from_copied_buffer(p, len));
}
static Out FromCopiedBuffer(const uint8_t* p, size_t len) {
return Out(
grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(p), len));
}
template <typename Buffer>
static Out FromCopiedBuffer(const Buffer& buffer) {
return FromCopiedBuffer(reinterpret_cast<const char*>(buffer.data()),

@ -106,6 +106,12 @@
*/
#define GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS \
"grpc.http2.min_ping_interval_without_data_ms"
/** Maximum time to allow a request to be:
(1) received by the server, but
(2) not requested by a RequestCall (in the completion queue based API)
before the request is cancelled */
#define GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS \
"grpc.server_max_unrequested_time_in_server"
/** Channel arg to override the http2 :scheme header */
#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
/** How many pings can the client send before needing to send a

@ -28,6 +28,8 @@
#include "absl/strings/string_view.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include <grpcpp/ext/otel_plugin.h>
namespace grpc {
namespace internal {
@ -88,6 +90,18 @@ class CsmObservabilityBuilder {
std::unique_ptr<grpc::internal::OpenTelemetryPluginBuilderImpl> builder_;
};
class OpenTelemetryPluginOption;
/// Creates an OpenTelemetryPluginOption that would add additional labels on
/// gRPC metrics to enhance observability for CSM users.
///
/// Sample Usage -
/// OpenTelemetryPluginBuilder()
/// .SetMeterProvider(provider)
/// .AddPluginOption(MakeCsmOpenTelemetryPluginOption())
/// .BuildAndRegisterGlobal();
std::unique_ptr<OpenTelemetryPluginOption> MakeCsmOpenTelemetryPluginOption();
} // namespace experimental
} // namespace grpc

@ -38,6 +38,11 @@ class OpenTelemetryPluginBuilderImpl;
namespace experimental {
class OpenTelemetryPluginOption {
public:
virtual ~OpenTelemetryPluginOption() = default;
};
/// The most common way to use this API is -
///
/// OpenTelemetryPluginBuilder().SetMeterProvider(provider).BuildAndRegister();
@ -76,6 +81,7 @@ class OpenTelemetryPluginBuilder {
"grpc.server.call.rcvd_total_compressed_message_size";
OpenTelemetryPluginBuilder();
~OpenTelemetryPluginBuilder();
/// If `SetMeterProvider()` is not called, no metrics are collected.
OpenTelemetryPluginBuilder& SetMeterProvider(
std::shared_ptr<opentelemetry::metrics::MeterProvider> meter_provider);
@ -95,6 +101,12 @@ class OpenTelemetryPluginBuilder {
OpenTelemetryPluginBuilder& SetGenericMethodAttributeFilter(
absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>
generic_method_attribute_filter);
/// Add a plugin option to add to the opentelemetry plugin being built. At
/// present, this type is an opaque type. Ownership of \a option is
/// transferred when `AddPluginOption` is invoked. A maximum of 64 plugin
/// options can be added.
OpenTelemetryPluginBuilder& AddPluginOption(
std::unique_ptr<OpenTelemetryPluginOption> option);
/// Registers a global plugin that acts on all channels and servers running on
/// the process.
void BuildAndRegisterGlobal();

@ -32,7 +32,6 @@ class ChannelTestPeer {
/// Provide the gRPC Core channel
grpc_channel* channel() const { return channel_->c_channel_; }
int registered_calls() const;
int registration_attempts() const;
private:
Channel* channel_; // not owned

8
package.xml generated

@ -1277,8 +1277,8 @@
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/internal_errqueue.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/lockfree_event.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/lockfree_event.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/native_dns_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/native_dns_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/posix_endpoint.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/posix_endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/posix_engine/posix_engine.cc" role="src" />
@ -1334,6 +1334,8 @@
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/grpc_polled_fd_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/iocp.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/iocp.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/native_windows_dns_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/native_windows_dns_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/win_socket.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/win_socket.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/windows/windows_endpoint.cc" role="src" />
@ -1887,8 +1889,6 @@
<file baseinstalldir="/" name="src/core/lib/transport/metadata_compression_traits.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/parsed_metadata.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/parsed_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/pid_controller.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/pid_controller.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/simple_slice_based_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_conversion.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_conversion.h" role="src" />

@ -16,3 +16,5 @@ setuptools==44.1.1
xds-protos==0.0.11
absl-py==1.4.0
googleapis-common-protos==1.61.0
opentelemetry-sdk==1.21.0
opentelemetry-api==1.21.0

@ -467,7 +467,7 @@ bool PrivateGenerator::PrintStub(
out->Print(
method_dict,
"response_deserializer=$ResponseModuleAndClass$.FromString,\n");
out->Print(")\n");
out->Print("_registered_method=True)\n");
}
}
}
@ -642,22 +642,27 @@ bool PrivateGenerator::PrintServiceClass(
args_dict["ArityMethodName"] = arity_method_name;
args_dict["PackageQualifiedService"] = package_qualified_service_name;
args_dict["Method"] = method->name();
out->Print(args_dict,
"return "
"grpc.experimental.$ArityMethodName$($RequestParameter$, "
"target, '/$PackageQualifiedService$/$Method$',\n");
out->Print(args_dict, "return grpc.experimental.$ArityMethodName$(\n");
{
IndentScope continuation_indent(out);
StringMap serializer_dict;
out->Print(args_dict, "$RequestParameter$,\n");
out->Print("target,\n");
out->Print(args_dict, "'/$PackageQualifiedService$/$Method$',\n");
serializer_dict["RequestModuleAndClass"] = request_module_and_class;
serializer_dict["ResponseModuleAndClass"] = response_module_and_class;
out->Print(serializer_dict,
"$RequestModuleAndClass$.SerializeToString,\n");
out->Print(serializer_dict, "$ResponseModuleAndClass$.FromString,\n");
out->Print("options, channel_credentials,\n");
out->Print(
"insecure, call_credentials, compression, wait_for_ready, "
"timeout, metadata)\n");
out->Print("options,\n");
out->Print("channel_credentials,\n");
out->Print("insecure,\n");
out->Print("call_credentials,\n");
out->Print("compression,\n");
out->Print("wait_for_ready,\n");
out->Print("timeout,\n");
out->Print("metadata,\n");
out->Print("_registered_method=True)\n");
}
}
}

@ -619,6 +619,17 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "switch",
language = "c++",
public_hdrs = ["lib/promise/switch.h"],
deps = [
"if",
"promise_factory",
"//:gpr_platform",
],
)
grpc_cc_library(
name = "promise_status",
external_deps = [
@ -736,15 +747,6 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "switch",
language = "c++",
public_hdrs = [
"lib/promise/detail/switch.h",
],
deps = ["//:gpr_platform"],
)
grpc_cc_library(
name = "basic_seq",
language = "c++",
@ -2173,7 +2175,7 @@ grpc_cc_library(
"forkable",
"init_internally",
"iomgr_port",
"native_dns_resolver",
"native_posix_dns_resolver",
"no_destruct",
"posix_event_engine_base_hdrs",
"posix_event_engine_closure",
@ -2220,6 +2222,20 @@ grpc_cc_library(
"windows_endpoint",
"windows_event_engine_listener",
"windows_iocp",
"windows_native_resolver",
"//:event_engine_base_hdrs",
"//:gpr",
],
)
grpc_cc_library(
name = "windows_native_resolver",
srcs = ["lib/event_engine/windows/native_windows_dns_resolver.cc"],
hdrs = ["lib/event_engine/windows/native_windows_dns_resolver.h"],
external_deps = ["absl/strings:str_format"],
deps = [
"error",
"status_helper",
"//:event_engine_base_hdrs",
"//:gpr",
],
@ -2519,12 +2535,12 @@ grpc_cc_library(
)
grpc_cc_library(
name = "native_dns_resolver",
name = "native_posix_dns_resolver",
srcs = [
"lib/event_engine/posix_engine/native_dns_resolver.cc",
"lib/event_engine/posix_engine/native_posix_dns_resolver.cc",
],
hdrs = [
"lib/event_engine/posix_engine/native_dns_resolver.h",
"lib/event_engine/posix_engine/native_posix_dns_resolver.h",
],
external_deps = [
"absl/functional:any_invocable",
@ -2607,20 +2623,6 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "pid_controller",
srcs = [
"lib/transport/pid_controller.cc",
],
hdrs = [
"lib/transport/pid_controller.h",
],
deps = [
"useful",
"//:gpr_platform",
],
)
grpc_cc_library(
name = "bdp_estimator",
srcs = [
@ -5490,6 +5492,7 @@ grpc_cc_library(
"channel_fwd",
"channel_stack_type",
"context",
"experiments",
"grpc_backend_metric_data",
"grpc_backend_metric_provider",
"map",
@ -5908,7 +5911,6 @@ grpc_cc_library(
"experiments",
"http2_settings",
"memory_quota",
"pid_controller",
"time",
"useful",
"//:gpr",
@ -6229,6 +6231,7 @@ grpc_cc_library(
"bitset",
"chaotic_good_frame_header",
"context",
"match",
"no_destruct",
"slice",
"slice_buffer",
@ -6252,6 +6255,7 @@ grpc_cc_library(
external_deps = [
"absl/status",
"absl/status:statusor",
"absl/strings",
],
deps = [
"bitset",
@ -6384,6 +6388,29 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "chaotic_good_transport",
srcs = [
"ext/transport/chaotic_good/chaotic_good_transport.cc",
],
hdrs = [
"ext/transport/chaotic_good/chaotic_good_transport.h",
],
external_deps = ["absl/random"],
language = "c++",
deps = [
"chaotic_good_frame",
"chaotic_good_frame_header",
"grpc_promise_endpoint",
"if",
"try_join",
"try_seq",
"//:gpr_platform",
"//:hpack_encoder",
"//:promise",
],
)
grpc_cc_library(
name = "chaotic_good_client_transport",
srcs = [
@ -6394,6 +6421,7 @@ grpc_cc_library(
],
external_deps = [
"absl/base:core_headers",
"absl/container:flat_hash_map",
"absl/random",
"absl/random:bit_gen_ref",
"absl/status",
@ -6404,9 +6432,11 @@ grpc_cc_library(
language = "c++",
deps = [
"activity",
"all_ok",
"arena",
"chaotic_good_frame",
"chaotic_good_frame_header",
"chaotic_good_transport",
"context",
"event_engine_wakeup_scheduler",
"for_each",
@ -6414,6 +6444,7 @@ grpc_cc_library(
"if",
"inter_activity_pipe",
"loop",
"map",
"match",
"memory_quota",
"mpsc",
@ -6430,6 +6461,63 @@ grpc_cc_library(
"//:grpc_base",
"//:hpack_encoder",
"//:hpack_parser",
"//:promise",
"//:ref_counted_ptr",
],
)
grpc_cc_library(
name = "chaotic_good_server_transport",
srcs = [
"ext/transport/chaotic_good/server_transport.cc",
],
hdrs = [
"ext/transport/chaotic_good/server_transport.h",
],
external_deps = [
"absl/base:core_headers",
"absl/container:flat_hash_map",
"absl/functional:any_invocable",
"absl/random",
"absl/random:bit_gen_ref",
"absl/status",
"absl/status:statusor",
"absl/types:optional",
"absl/types:variant",
],
language = "c++",
deps = [
"1999",
"activity",
"arena",
"chaotic_good_frame",
"chaotic_good_frame_header",
"chaotic_good_transport",
"context",
"default_event_engine",
"event_engine_wakeup_scheduler",
"for_each",
"grpc_promise_endpoint",
"if",
"inter_activity_pipe",
"loop",
"memory_quota",
"mpsc",
"pipe",
"poll",
"resource_quota",
"seq",
"slice",
"slice_buffer",
"switch",
"try_join",
"try_seq",
"//:exec_ctx",
"//:gpr",
"//:gpr_platform",
"//:grpc_base",
"//:hpack_encoder",
"//:hpack_parser",
"//:ref_counted_ptr",
],
)

@ -37,6 +37,7 @@
#include "src/core/lib/channel/context.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/map.h"
#include "src/core/lib/slice/slice.h"
@ -47,8 +48,15 @@ namespace grpc_core {
TraceFlag grpc_backend_metric_filter_trace(false, "backend_metric_filter");
absl::optional<std::string> BackendMetricFilter::MaybeSerializeBackendMetrics(
BackendMetricProvider* provider) const {
const NoInterceptor BackendMetricFilter::Call::OnClientInitialMetadata;
const NoInterceptor BackendMetricFilter::Call::OnServerInitialMetadata;
const NoInterceptor BackendMetricFilter::Call::OnClientToServerMessage;
const NoInterceptor BackendMetricFilter::Call::OnServerToClientMessage;
const NoInterceptor BackendMetricFilter::Call::OnFinalize;
namespace {
absl::optional<std::string> MaybeSerializeBackendMetrics(
BackendMetricProvider* provider) {
if (provider == nullptr) return absl::nullopt;
BackendMetricData data = provider->GetBackendMetricData();
upb::Arena arena;
@ -107,17 +115,27 @@ absl::optional<std::string> BackendMetricFilter::MaybeSerializeBackendMetrics(
xds_data_orca_v3_OrcaLoadReport_serialize(response, arena.ptr(), &len);
return std::string(buf, len);
}
} // namespace
const grpc_channel_filter LegacyBackendMetricFilter::kFilter =
MakePromiseBasedFilter<LegacyBackendMetricFilter, FilterEndpoint::kServer>(
"backend_metric");
const grpc_channel_filter BackendMetricFilter::kFilter =
MakePromiseBasedFilter<BackendMetricFilter, FilterEndpoint::kServer>(
"backend_metric");
absl::StatusOr<LegacyBackendMetricFilter> LegacyBackendMetricFilter::Create(
const ChannelArgs&, ChannelFilter::Args) {
return LegacyBackendMetricFilter();
}
absl::StatusOr<BackendMetricFilter> BackendMetricFilter::Create(
const ChannelArgs&, ChannelFilter::Args) {
return BackendMetricFilter();
}
ArenaPromise<ServerMetadataHandle> BackendMetricFilter::MakeCallPromise(
ArenaPromise<ServerMetadataHandle> LegacyBackendMetricFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
return ArenaPromise<ServerMetadataHandle>(Map(
next_promise_factory(std::move(call_args)),
@ -148,10 +166,39 @@ ArenaPromise<ServerMetadataHandle> BackendMetricFilter::MakeCallPromise(
}));
}
void BackendMetricFilter::Call::OnServerTrailingMetadata(ServerMetadata& md) {
auto* ctx = &GetContext<
grpc_call_context_element>()[GRPC_CONTEXT_BACKEND_METRIC_PROVIDER];
if (ctx == nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_filter_trace)) {
gpr_log(GPR_INFO, "[%p] No BackendMetricProvider.", this);
}
return;
}
absl::optional<std::string> serialized = MaybeSerializeBackendMetrics(
reinterpret_cast<BackendMetricProvider*>(ctx->value));
if (serialized.has_value() && !serialized->empty()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_filter_trace)) {
gpr_log(GPR_INFO, "[%p] Backend metrics serialized. size: %" PRIuPTR,
this, serialized->size());
}
md.Set(EndpointLoadMetricsBinMetadata(),
Slice::FromCopiedString(std::move(*serialized)));
} else if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_filter_trace)) {
gpr_log(GPR_INFO, "[%p] No backend metrics.", this);
}
}
void RegisterBackendMetricFilter(CoreConfiguration::Builder* builder) {
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &BackendMetricFilter::kFilter)
.IfHasChannelArg(GRPC_ARG_SERVER_CALL_METRIC_RECORDING);
if (IsV3BackendMetricFilterEnabled()) {
builder->channel_init()
->RegisterFilter<BackendMetricFilter>(GRPC_SERVER_CHANNEL)
.IfHasChannelArg(GRPC_ARG_SERVER_CALL_METRIC_RECORDING);
} else {
builder->channel_init()
->RegisterFilter<LegacyBackendMetricFilter>(GRPC_SERVER_CHANNEL)
.IfHasChannelArg(GRPC_ARG_SERVER_CALL_METRIC_RECORDING);
}
}
} // namespace grpc_core

@ -31,20 +31,34 @@
namespace grpc_core {
class BackendMetricFilter : public ChannelFilter {
class LegacyBackendMetricFilter : public ChannelFilter {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<BackendMetricFilter> Create(const ChannelArgs& args,
ChannelFilter::Args);
static absl::StatusOr<LegacyBackendMetricFilter> Create(
const ChannelArgs& args, ChannelFilter::Args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
};
class BackendMetricFilter : public ImplementChannelFilter<BackendMetricFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<BackendMetricFilter> Create(const ChannelArgs& args,
ChannelFilter::Args);
private:
absl::optional<std::string> MaybeSerializeBackendMetrics(
BackendMetricProvider* provider) const;
class Call {
public:
static const NoInterceptor OnClientInitialMetadata;
static const NoInterceptor OnServerInitialMetadata;
void OnServerTrailingMetadata(ServerMetadata& md);
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
};
} // namespace grpc_core

@ -296,13 +296,13 @@ const grpc_channel_filter MaxAgeFilter::kFilter =
void RegisterChannelIdleFilters(CoreConfiguration::Builder* builder) {
if (!IsV3ChannelIdleFiltersEnabled()) return;
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_CHANNEL, &ClientIdleFilter::kFilter)
->RegisterFilter<ClientIdleFilter>(GRPC_CLIENT_CHANNEL)
.ExcludeFromMinimalStack()
.If([](const ChannelArgs& channel_args) {
return GetClientIdleTimeout(channel_args) != Duration::Infinity();
});
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &MaxAgeFilter::kFilter)
->RegisterFilter<MaxAgeFilter>(GRPC_SERVER_CHANNEL)
.ExcludeFromMinimalStack()
.If([](const ChannelArgs& channel_args) {
return MaxAgeFilter::Config::FromChannelArgs(channel_args).enable();

@ -302,13 +302,13 @@ const grpc_channel_filter LegacyMaxAgeFilter::kFilter =
void RegisterLegacyChannelIdleFilters(CoreConfiguration::Builder* builder) {
if (IsV3ChannelIdleFiltersEnabled()) return;
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_CHANNEL, &LegacyClientIdleFilter::kFilter)
->RegisterFilter<LegacyClientIdleFilter>(GRPC_CLIENT_CHANNEL)
.ExcludeFromMinimalStack()
.If([](const ChannelArgs& channel_args) {
return GetClientIdleTimeout(channel_args) != Duration::Infinity();
});
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &LegacyMaxAgeFilter::kFilter)
->RegisterFilter<LegacyMaxAgeFilter>(GRPC_SERVER_CHANNEL)
.ExcludeFromMinimalStack()
.If([](const ChannelArgs& channel_args) {
return LegacyMaxAgeFilter::Config::FromChannelArgs(channel_args)

@ -69,6 +69,9 @@ class EndpointList::Endpoint::Helper
grpc_connectivity_state state, const absl::Status& status,
RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker) override {
auto old_state = std::exchange(endpoint_->connectivity_state_, state);
if (!old_state.has_value()) {
++endpoint_->endpoint_list_->num_endpoints_seen_initial_state_;
}
endpoint_->picker_ = std::move(picker);
endpoint_->OnStateUpdate(old_state, state, status);
}
@ -181,11 +184,4 @@ void EndpointList::ResetBackoffLocked() {
}
}
bool EndpointList::AllEndpointsSeenInitialState() const {
for (const auto& endpoint : endpoints_) {
if (!endpoint->connectivity_state().has_value()) return false;
}
return true;
}
} // namespace grpc_core

@ -199,7 +199,9 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
// Returns true if all endpoints have seen their initial connectivity
// state notification.
bool AllEndpointsSeenInitialState() const;
bool AllEndpointsSeenInitialState() const {
return num_endpoints_seen_initial_state_ == size();
}
private:
// Returns the parent policy's helper. Needed because the accessor
@ -210,6 +212,7 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
RefCountedPtr<LoadBalancingPolicy> policy_;
const char* tracer_;
std::vector<OrphanablePtr<Endpoint>> endpoints_;
size_t num_endpoints_seen_initial_state_ = 0;
};
} // namespace grpc_core

@ -1928,8 +1928,7 @@ void RegisterGrpcLbPolicy(CoreConfiguration::Builder* builder) {
builder->lb_policy_registry()->RegisterLoadBalancingPolicyFactory(
std::make_unique<GrpcLbFactory>());
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_SUBCHANNEL,
&ClientLoadReportingFilter::kFilter)
->RegisterFilter<ClientLoadReportingFilter>(GRPC_CLIENT_SUBCHANNEL)
.IfChannelArg(GRPC_ARG_GRPCLB_ENABLE_LOAD_REPORTING_FILTER, false);
}

@ -224,7 +224,9 @@ class PickFirst : public LoadBalancingPolicy {
private:
// Returns true if all subchannels have seen their initial
// connectivity state notifications.
bool AllSubchannelsSeenInitialState();
bool AllSubchannelsSeenInitialState() const {
return num_subchannels_seen_initial_notification_ == size();
}
// Looks through subchannels_ starting from attempting_index_ to
// find the first one not currently in TRANSIENT_FAILURE, then
@ -255,6 +257,8 @@ class PickFirst : public LoadBalancingPolicy {
// TODO(roth): Remove this when we remove the Happy Eyeballs experiment.
bool in_transient_failure_ = false;
size_t num_subchannels_seen_initial_notification_ = 0;
// The index into subchannels_ to which we are currently attempting
// to connect during the initial Happy Eyeballs pass. Once the
// initial pass is over, this will be equal to size().
@ -754,6 +758,11 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange(
seen_transient_failure_ = true;
subchannel_list_->last_failure_ = connectivity_status_;
}
// If this is the initial connectivity state update for this subchannel,
// increment the counter in the subchannel list.
if (!old_state.has_value()) {
++subchannel_list_->num_subchannels_seen_initial_notification_;
}
// If we haven't yet seen the initial connectivity state notification
// for all subchannels, do nothing.
if (!subchannel_list_->AllSubchannelsSeenInitialState()) return;
@ -1122,13 +1131,6 @@ void PickFirst::SubchannelList::ResetBackoffLocked() {
}
}
bool PickFirst::SubchannelList::AllSubchannelsSeenInitialState() {
for (auto& sd : subchannels_) {
if (!sd.connectivity_state().has_value()) return false;
}
return true;
}
void PickFirst::SubchannelList::StartConnectingNextSubchannel() {
// Find the next subchannel not in state TRANSIENT_FAILURE.
// We skip subchannels in state TRANSIENT_FAILURE to avoid a

@ -312,7 +312,8 @@ class XdsResolver : public Resolver {
RouteConfigData::RouteEntry* route_;
};
class ClusterSelectionFilter : public ChannelFilter {
class ClusterSelectionFilter
: public ImplementChannelFilter<ClusterSelectionFilter> {
public:
const static grpc_channel_filter kFilter;
@ -322,8 +323,15 @@ class XdsResolver : public Resolver {
}
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
void OnClientInitialMetadata(ClientMetadata& md);
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
explicit ClusterSelectionFilter(ChannelFilter::Args filter_args)
@ -374,6 +382,16 @@ class XdsResolver : public Resolver {
std::map<absl::string_view, WeakRefCountedPtr<ClusterRef>> cluster_ref_map_;
};
const NoInterceptor
XdsResolver::ClusterSelectionFilter::Call::OnServerInitialMetadata;
const NoInterceptor
XdsResolver::ClusterSelectionFilter::Call::OnServerTrailingMetadata;
const NoInterceptor
XdsResolver::ClusterSelectionFilter::Call::OnClientToServerMessage;
const NoInterceptor
XdsResolver::ClusterSelectionFilter::Call::OnServerToClientMessage;
const NoInterceptor XdsResolver::ClusterSelectionFilter::Call::OnFinalize;
//
// XdsResolver::RouteConfigData::RouteListIterator
//
@ -835,9 +853,8 @@ const grpc_channel_filter XdsResolver::ClusterSelectionFilter::kFilter =
kFilterExaminesServerInitialMetadata>(
"cluster_selection_filter");
ArenaPromise<ServerMetadataHandle>
XdsResolver::ClusterSelectionFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
void XdsResolver::ClusterSelectionFilter::Call::OnClientInitialMetadata(
ClientMetadata&) {
auto* service_config_call_data =
static_cast<ClientChannelServiceConfigCallData*>(
GetContext<grpc_call_context_element>()
@ -856,7 +873,6 @@ XdsResolver::ClusterSelectionFilter::MakeCallPromise(
[cluster = std::move(cluster)]() mutable { cluster.reset(); });
}
}
return next_promise_factory(std::move(call_args));
}
//

@ -54,7 +54,8 @@ namespace grpc_core {
namespace {
class ServiceConfigChannelArgFilter : public ChannelFilter {
class ServiceConfigChannelArgFilter
: public ImplementChannelFilter<ServiceConfigChannelArgFilter> {
public:
static absl::StatusOr<ServiceConfigChannelArgFilter> Create(
const ChannelArgs& args, ChannelFilter::Args) {
@ -74,28 +75,43 @@ class ServiceConfigChannelArgFilter : public ChannelFilter {
}
}
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
void OnClientInitialMetadata(ClientMetadata& md,
ServiceConfigChannelArgFilter* filter);
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
RefCountedPtr<ServiceConfig> service_config_;
};
ArenaPromise<ServerMetadataHandle>
ServiceConfigChannelArgFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
const NoInterceptor
ServiceConfigChannelArgFilter::Call::OnServerInitialMetadata;
const NoInterceptor
ServiceConfigChannelArgFilter::Call::OnServerTrailingMetadata;
const NoInterceptor
ServiceConfigChannelArgFilter::Call::OnClientToServerMessage;
const NoInterceptor
ServiceConfigChannelArgFilter::Call::OnServerToClientMessage;
const NoInterceptor ServiceConfigChannelArgFilter::Call::OnFinalize;
void ServiceConfigChannelArgFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, ServiceConfigChannelArgFilter* filter) {
const ServiceConfigParser::ParsedConfigVector* method_configs = nullptr;
if (service_config_ != nullptr) {
method_configs = service_config_->GetMethodParsedConfigVector(
call_args.client_initial_metadata->get_pointer(HttpPathMetadata())
->c_slice());
if (filter->service_config_ != nullptr) {
method_configs = filter->service_config_->GetMethodParsedConfigVector(
md.get_pointer(HttpPathMetadata())->c_slice());
}
auto* arena = GetContext<Arena>();
auto* service_config_call_data = arena->New<ServiceConfigCallData>(
arena, GetContext<grpc_call_context_element>());
service_config_call_data->SetServiceConfig(service_config_, method_configs);
return next_promise_factory(std::move(call_args));
service_config_call_data->SetServiceConfig(filter->service_config_,
method_configs);
}
const grpc_channel_filter kServiceConfigChannelArgFilter =
@ -112,7 +128,7 @@ void RegisterServiceConfigChannelArgFilter(
&kServiceConfigChannelArgFilter)
.ExcludeFromMinimalStack()
.IfHasChannelArg(GRPC_ARG_SERVICE_CONFIG)
.Before({&ClientMessageSizeFilter::kFilter});
.Before<ClientMessageSizeFilter>();
}
} // namespace grpc_core

@ -54,6 +54,11 @@
namespace grpc_core {
TraceFlag grpc_fault_injection_filter_trace(false, "fault_injection_filter");
const NoInterceptor FaultInjectionFilter::Call::OnServerInitialMetadata;
const NoInterceptor FaultInjectionFilter::Call::OnServerTrailingMetadata;
const NoInterceptor FaultInjectionFilter::Call::OnClientToServerMessage;
const NoInterceptor FaultInjectionFilter::Call::OnServerToClientMessage;
const NoInterceptor FaultInjectionFilter::Call::OnFinalize;
namespace {
@ -144,23 +149,22 @@ FaultInjectionFilter::FaultInjectionFilter(ChannelFilter::Args filter_args)
mu_(new Mutex) {}
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> FaultInjectionFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
auto decision = MakeInjectionDecision(call_args.client_initial_metadata);
ArenaPromise<absl::Status> FaultInjectionFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, FaultInjectionFilter* filter) {
auto decision = filter->MakeInjectionDecision(md);
if (GRPC_TRACE_FLAG_ENABLED(grpc_fault_injection_filter_trace)) {
gpr_log(GPR_INFO, "chand=%p: Fault injection triggered %s", this,
decision.ToString().c_str());
}
auto delay = decision.DelayUntil();
return TrySeq(
Sleep(delay),
[decision = std::move(decision)]() { return decision.MaybeAbort(); },
next_promise_factory(std::move(call_args)));
return TrySeq(Sleep(delay), [decision = std::move(decision)]() {
return decision.MaybeAbort();
});
}
FaultInjectionFilter::InjectionDecision
FaultInjectionFilter::MakeInjectionDecision(
const ClientMetadataHandle& initial_metadata) {
const ClientMetadata& initial_metadata) {
// Fetch the fault injection policy from the service config, based on the
// relative index for which policy should this CallData use.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
@ -188,15 +192,15 @@ FaultInjectionFilter::MakeInjectionDecision(
!fi_policy->delay_percentage_header.empty()) {
std::string buffer;
if (!fi_policy->abort_code_header.empty() && abort_code == GRPC_STATUS_OK) {
auto value = initial_metadata->GetStringValue(
fi_policy->abort_code_header, &buffer);
auto value = initial_metadata.GetStringValue(fi_policy->abort_code_header,
&buffer);
if (value.has_value()) {
grpc_status_code_from_int(
AsInt<int>(*value).value_or(GRPC_STATUS_UNKNOWN), &abort_code);
}
}
if (!fi_policy->abort_percentage_header.empty()) {
auto value = initial_metadata->GetStringValue(
auto value = initial_metadata.GetStringValue(
fi_policy->abort_percentage_header, &buffer);
if (value.has_value()) {
abort_percentage_numerator = std::min(
@ -205,14 +209,14 @@ FaultInjectionFilter::MakeInjectionDecision(
}
if (!fi_policy->delay_header.empty() && delay == Duration::Zero()) {
auto value =
initial_metadata->GetStringValue(fi_policy->delay_header, &buffer);
initial_metadata.GetStringValue(fi_policy->delay_header, &buffer);
if (value.has_value()) {
delay = Duration::Milliseconds(
std::max(AsInt<int64_t>(*value).value_or(0), int64_t{0}));
}
}
if (!fi_policy->delay_percentage_header.empty()) {
auto value = initial_metadata->GetStringValue(
auto value = initial_metadata.GetStringValue(
fi_policy->delay_percentage_header, &buffer);
if (value.has_value()) {
delay_percentage_numerator = std::min(

@ -40,7 +40,8 @@ namespace grpc_core {
// of the ordinary channel stack. The fault injection filter fetches fault
// injection policy from the method config of service config returned by the
// resolver, and enforces the fault injection policy.
class FaultInjectionFilter : public ChannelFilter {
class FaultInjectionFilter
: public ImplementChannelFilter<FaultInjectionFilter> {
public:
static const grpc_channel_filter kFilter;
@ -48,15 +49,23 @@ class FaultInjectionFilter : public ChannelFilter {
const ChannelArgs& args, ChannelFilter::Args filter_args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
ArenaPromise<absl::Status> OnClientInitialMetadata(
ClientMetadata& md, FaultInjectionFilter* filter);
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
explicit FaultInjectionFilter(ChannelFilter::Args filter_args);
class InjectionDecision;
InjectionDecision MakeInjectionDecision(
const ClientMetadataHandle& initial_metadata);
const ClientMetadata& initial_metadata);
// The relative index of instances of the same filter.
size_t index_;

@ -37,6 +37,12 @@
namespace grpc_core {
const NoInterceptor ClientAuthorityFilter::Call::OnServerInitialMetadata;
const NoInterceptor ClientAuthorityFilter::Call::OnServerTrailingMetadata;
const NoInterceptor ClientAuthorityFilter::Call::OnClientToServerMessage;
const NoInterceptor ClientAuthorityFilter::Call::OnServerToClientMessage;
const NoInterceptor ClientAuthorityFilter::Call::OnFinalize;
absl::StatusOr<ClientAuthorityFilter> ClientAuthorityFilter::Create(
const ChannelArgs& args, ChannelFilter::Args) {
absl::optional<absl::string_view> default_authority =
@ -49,17 +55,12 @@ absl::StatusOr<ClientAuthorityFilter> ClientAuthorityFilter::Create(
return ClientAuthorityFilter(Slice::FromCopiedString(*default_authority));
}
ArenaPromise<ServerMetadataHandle> ClientAuthorityFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
void ClientAuthorityFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, ClientAuthorityFilter* filter) {
// If no authority is set, set the default authority.
if (call_args.client_initial_metadata->get_pointer(HttpAuthorityMetadata()) ==
nullptr) {
call_args.client_initial_metadata->Set(HttpAuthorityMetadata(),
default_authority_.Ref());
if (md.get_pointer(HttpAuthorityMetadata()) == nullptr) {
md.Set(HttpAuthorityMetadata(), filter->default_authority_.Ref());
}
// We have no asynchronous work, so we can just ask the next promise to run,
// passing down initial_metadata.
return next_promise_factory(std::move(call_args));
}
const grpc_channel_filter ClientAuthorityFilter::kFilter =
@ -75,14 +76,13 @@ bool NeedsClientAuthorityFilter(const ChannelArgs& args) {
void RegisterClientAuthorityFilter(CoreConfiguration::Builder* builder) {
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, &ClientAuthorityFilter::kFilter)
->RegisterFilter<ClientAuthorityFilter>(GRPC_CLIENT_SUBCHANNEL)
.If(NeedsClientAuthorityFilter)
.Before({&ClientAuthFilter::kFilter});
.Before<ClientAuthFilter>();
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL,
&ClientAuthorityFilter::kFilter)
->RegisterFilter<ClientAuthorityFilter>(GRPC_CLIENT_DIRECT_CHANNEL)
.If(NeedsClientAuthorityFilter)
.Before({&ClientAuthFilter::kFilter});
.Before<ClientAuthFilter>();
}
} // namespace grpc_core

@ -34,16 +34,24 @@
namespace grpc_core {
class ClientAuthorityFilter final : public ChannelFilter {
class ClientAuthorityFilter final
: public ImplementChannelFilter<ClientAuthorityFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<ClientAuthorityFilter> Create(const ChannelArgs& args,
ChannelFilter::Args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
void OnClientInitialMetadata(ClientMetadata& md,
ClientAuthorityFilter* filter);
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
explicit ClientAuthorityFilter(Slice default_authority)

@ -42,47 +42,49 @@ bool IsBuildingHttpLikeTransport(const ChannelArgs& args) {
void RegisterHttpFilters(CoreConfiguration::Builder* builder) {
if (IsV3CompressionFilterEnabled()) {
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_SUBCHANNEL,
&ClientCompressionFilter::kFilter)
->RegisterFilter<ClientCompressionFilter>(GRPC_CLIENT_SUBCHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter});
.After<HttpClientFilter>()
.After<ClientMessageSizeFilter>();
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL,
&ClientCompressionFilter::kFilter)
->RegisterFilter<ClientCompressionFilter>(GRPC_CLIENT_DIRECT_CHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter});
.After<HttpClientFilter>()
.After<ClientMessageSizeFilter>();
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerCompressionFilter::kFilter)
->RegisterFilter<ServerCompressionFilter>(GRPC_SERVER_CHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&HttpServerFilter::kFilter, &ServerMessageSizeFilter::kFilter});
.After<HttpServerFilter>()
.After<ServerMessageSizeFilter>();
} else {
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_SUBCHANNEL,
&LegacyClientCompressionFilter::kFilter)
->RegisterFilter<LegacyClientCompressionFilter>(GRPC_CLIENT_SUBCHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter});
.After<HttpClientFilter>()
.After<ClientMessageSizeFilter>();
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL,
&LegacyClientCompressionFilter::kFilter)
->RegisterFilter<LegacyClientCompressionFilter>(
GRPC_CLIENT_DIRECT_CHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&HttpClientFilter::kFilter, &ClientMessageSizeFilter::kFilter});
.After<HttpClientFilter>()
.After<ClientMessageSizeFilter>();
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL,
&LegacyServerCompressionFilter::kFilter)
->RegisterFilter<LegacyServerCompressionFilter>(GRPC_SERVER_CHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&HttpServerFilter::kFilter, &ServerMessageSizeFilter::kFilter});
.After<HttpServerFilter>()
.After<ServerMessageSizeFilter>();
}
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_SUBCHANNEL, &HttpClientFilter::kFilter)
->RegisterFilter<HttpClientFilter>(GRPC_CLIENT_SUBCHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&ClientMessageSizeFilter::kFilter});
.After<ClientMessageSizeFilter>();
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, &HttpClientFilter::kFilter)
->RegisterFilter<HttpClientFilter>(GRPC_CLIENT_DIRECT_CHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&ClientMessageSizeFilter::kFilter});
.After<ClientMessageSizeFilter>();
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &HttpServerFilter::kFilter)
->RegisterFilter<HttpServerFilter>(GRPC_SERVER_CHANNEL)
.If(IsBuildingHttpLikeTransport)
.After({&ServerMessageSizeFilter::kFilter});
.After<ServerMessageSizeFilter>();
}
} // namespace grpc_core

@ -72,6 +72,10 @@ constexpr char kEncodedIpv4AddressLengthString[] = "08";
constexpr char kEncodedIpv6AddressLengthString[] = "32";
constexpr char kEmptyAddressLengthString[] = "00";
const NoInterceptor ServerLoadReportingFilter::Call::OnServerInitialMetadata;
const NoInterceptor ServerLoadReportingFilter::Call::OnClientToServerMessage;
const NoInterceptor ServerLoadReportingFilter::Call::OnServerToClientMessage;
absl::StatusOr<ServerLoadReportingFilter> ServerLoadReportingFilter::Create(
const ChannelArgs& channel_args, ChannelFilter::Args) {
// Find and record the peer_identity.
@ -93,9 +97,9 @@ absl::StatusOr<ServerLoadReportingFilter> ServerLoadReportingFilter::Create(
namespace {
std::string GetCensusSafeClientIpString(
const ClientMetadataHandle& initial_metadata) {
const ClientMetadata& initial_metadata) {
// Find the client URI string.
Slice* client_uri_slice = initial_metadata->get_pointer(PeerString());
const Slice* client_uri_slice = initial_metadata.get_pointer(PeerString());
if (client_uri_slice == nullptr) {
gpr_log(GPR_ERROR,
"Unable to extract client URI string (peer string) from gRPC "
@ -139,8 +143,8 @@ std::string GetCensusSafeClientIpString(
}
}
std::string MakeClientIpAndLrToken(
absl::string_view lr_token, const ClientMetadataHandle& initial_metadata) {
std::string MakeClientIpAndLrToken(absl::string_view lr_token,
const ClientMetadata& initial_metadata) {
std::string client_ip = GetCensusSafeClientIpString(initial_metadata);
absl::string_view prefix;
switch (client_ip.length()) {
@ -176,89 +180,73 @@ const char* GetStatusTagForStatus(grpc_status_code status) {
}
} // namespace
ArenaPromise<ServerMetadataHandle> ServerLoadReportingFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
void ServerLoadReportingFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, ServerLoadReportingFilter* filter) {
// Gather up basic facts about the request
Slice service_method;
if (const Slice* path =
call_args.client_initial_metadata->get_pointer(HttpPathMetadata())) {
if (const Slice* path = md.get_pointer(HttpPathMetadata())) {
service_method = path->Ref();
}
std::string target_host;
if (const Slice* authority = call_args.client_initial_metadata->get_pointer(
HttpAuthorityMetadata())) {
target_host = absl::AsciiStrToLower(authority->as_string_view());
if (const Slice* authority = md.get_pointer(HttpAuthorityMetadata())) {
target_host_ = absl::AsciiStrToLower(authority->as_string_view());
}
std::string client_ip_and_lr_token;
auto lb_token = call_args.client_initial_metadata->Take(LbTokenMetadata())
.value_or(Slice());
client_ip_and_lr_token = MakeClientIpAndLrToken(
lb_token.as_string_view(), call_args.client_initial_metadata);
auto lb_token = md.Take(LbTokenMetadata()).value_or(Slice());
client_ip_and_lr_token_ =
MakeClientIpAndLrToken(lb_token.as_string_view(), md);
// Record the beginning of the request
opencensus::stats::Record(
{{::grpc::load_reporter::MeasureStartCount(), 1}},
{{::grpc::load_reporter::TagKeyToken(),
{client_ip_and_lr_token.data(), client_ip_and_lr_token.length()}},
{client_ip_and_lr_token_.data(), client_ip_and_lr_token_.length()}},
{::grpc::load_reporter::TagKeyHost(),
{target_host.data(), target_host.length()}},
{target_host_.data(), target_host_.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{peer_identity_.data(), peer_identity_.length()}}});
// Returned promise runs the rest of the request, then reports costs and
// records measurements
return ArenaPromise<ServerMetadataHandle>(Seq(
// Call down the stack
next_promise_factory(std::move(call_args)),
// And then record the call result
[this, client_ip_and_lr_token,
target_host](ServerMetadataHandle trailing_metadata) {
const auto& costs = trailing_metadata->Take(LbCostBinMetadata());
for (const auto& cost : costs) {
opencensus::stats::Record(
{{::grpc::load_reporter::MeasureOtherCallMetric(), cost.cost}},
{{::grpc::load_reporter::TagKeyToken(),
{client_ip_and_lr_token.data(),
client_ip_and_lr_token.length()}},
{::grpc::load_reporter::TagKeyHost(),
{target_host.data(), target_host.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{peer_identity_.data(), peer_identity_.length()}},
{::grpc::load_reporter::TagKeyMetricName(),
{cost.name.data(), cost.name.length()}}});
}
GetContext<CallFinalization>()->Add([this, client_ip_and_lr_token,
target_host](
const grpc_call_final_info*
final_info) {
if (final_info == nullptr) return;
// After the last bytes have been placed on the wire we record
// final measurements
opencensus::stats::Record(
{{::grpc::load_reporter::MeasureEndCount(), 1},
{::grpc::load_reporter::MeasureEndBytesSent(),
final_info->stats.transport_stream_stats.outgoing.data_bytes},
{::grpc::load_reporter::MeasureEndBytesReceived(),
final_info->stats.transport_stream_stats.incoming.data_bytes},
{::grpc::load_reporter::MeasureEndLatencyMs(),
gpr_time_to_millis(final_info->stats.latency)}},
{{::grpc::load_reporter::TagKeyToken(),
{client_ip_and_lr_token.data(),
client_ip_and_lr_token.length()}},
{::grpc::load_reporter::TagKeyHost(),
{target_host.data(), target_host.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{peer_identity_.data(), peer_identity_.length()}},
{::grpc::load_reporter::TagKeyStatus(),
GetStatusTagForStatus(final_info->final_status)}});
});
return Immediate(std::move(trailing_metadata));
}));
{filter->peer_identity_.data(), filter->peer_identity_.length()}}});
}
namespace {
const grpc_channel_filter kFilter =
void ServerLoadReportingFilter::Call::OnServerTrailingMetadata(
ServerMetadata& md, ServerLoadReportingFilter* filter) {
const auto& costs = md.Take(LbCostBinMetadata());
for (const auto& cost : costs) {
opencensus::stats::Record(
{{::grpc::load_reporter::MeasureOtherCallMetric(), cost.cost}},
{{::grpc::load_reporter::TagKeyToken(),
{client_ip_and_lr_token_.data(), client_ip_and_lr_token_.length()}},
{::grpc::load_reporter::TagKeyHost(),
{target_host_.data(), target_host_.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{filter->peer_identity_.data(), filter->peer_identity_.length()}},
{::grpc::load_reporter::TagKeyMetricName(),
{cost.name.data(), cost.name.length()}}});
}
}
void ServerLoadReportingFilter::Call::OnFinalize(
const grpc_call_final_info* final_info, ServerLoadReportingFilter* filter) {
if (final_info == nullptr) return;
// After the last bytes have been placed on the wire we record
// final measurements
opencensus::stats::Record(
{{::grpc::load_reporter::MeasureEndCount(), 1},
{::grpc::load_reporter::MeasureEndBytesSent(),
final_info->stats.transport_stream_stats.outgoing.data_bytes},
{::grpc::load_reporter::MeasureEndBytesReceived(),
final_info->stats.transport_stream_stats.incoming.data_bytes},
{::grpc::load_reporter::MeasureEndLatencyMs(),
gpr_time_to_millis(final_info->stats.latency)}},
{{::grpc::load_reporter::TagKeyToken(),
{client_ip_and_lr_token_.data(), client_ip_and_lr_token_.length()}},
{::grpc::load_reporter::TagKeyHost(),
{target_host_.data(), target_host_.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{filter->peer_identity_.data(), filter->peer_identity_.length()}},
{::grpc::load_reporter::TagKeyStatus(),
GetStatusTagForStatus(final_info->final_status)}});
}
const grpc_channel_filter ServerLoadReportingFilter::kFilter =
MakePromiseBasedFilter<ServerLoadReportingFilter, FilterEndpoint::kServer>(
"server_load_reporting");
} // namespace
// TODO(juanlishen): We should register the filter during grpc initialization
// time once OpenCensus is compatible with our build system. For now, we force
@ -276,7 +264,7 @@ struct ServerLoadReportingFilterStaticRegistrar {
grpc::load_reporter::MeasureEndLatencyMs();
grpc::load_reporter::MeasureOtherCallMetric();
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &kFilter)
->RegisterFilter<ServerLoadReportingFilter>(GRPC_SERVER_CHANNEL)
.IfChannelArg(GRPC_ARG_ENABLE_LOAD_REPORTING, false);
});
}

@ -34,8 +34,11 @@
namespace grpc_core {
class ServerLoadReportingFilter : public ChannelFilter {
class ServerLoadReportingFilter
: public ImplementChannelFilter<ServerLoadReportingFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<ServerLoadReportingFilter> Create(
const ChannelArgs& args, ChannelFilter::Args);
@ -43,9 +46,22 @@ class ServerLoadReportingFilter : public ChannelFilter {
const char* peer_identity() { return peer_identity_.c_str(); }
size_t peer_identity_len() { return peer_identity_.length(); }
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
void OnClientInitialMetadata(ClientMetadata& md,
ServerLoadReportingFilter* filter);
static const NoInterceptor OnServerInitialMetadata;
void OnServerTrailingMetadata(ServerMetadata& md,
ServerLoadReportingFilter* filter);
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
void OnFinalize(const grpc_call_final_info* final_info,
ServerLoadReportingFilter* filter);
private:
std::string client_ip_and_lr_token_;
std::string target_host_;
};
private:
// The peer's authenticated identity.

@ -536,11 +536,11 @@ void RegisterLoggingFilter(LoggingSink* sink) {
g_logging_sink = sink;
CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) {
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerLoggingFilter::kFilter)
->RegisterFilter<ServerLoggingFilter>(GRPC_SERVER_CHANNEL)
// TODO(yashykt) : Figure out a good place to place this channel arg
.IfChannelArg("grpc.experimental.enable_observability", true);
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_CHANNEL, &ClientLoggingFilter::kFilter)
->RegisterFilter<ClientLoggingFilter>(GRPC_CLIENT_CHANNEL)
// TODO(yashykt) : Figure out a good place to place this channel arg
.IfChannelArg("grpc.experimental.enable_observability", true);
});

@ -240,12 +240,10 @@ bool HasMessageSizeLimits(const ChannelArgs& channel_args) {
void RegisterMessageSizeFilter(CoreConfiguration::Builder* builder) {
MessageSizeParser::Register(builder);
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_SUBCHANNEL,
&ClientMessageSizeFilter::kFilter)
->RegisterFilter<ClientMessageSizeFilter>(GRPC_CLIENT_SUBCHANNEL)
.ExcludeFromMinimalStack();
builder->channel_init()
->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL,
&ClientMessageSizeFilter::kFilter)
->RegisterFilter<ClientMessageSizeFilter>(GRPC_CLIENT_DIRECT_CHANNEL)
.ExcludeFromMinimalStack()
.If(HasMessageSizeLimits)
// TODO(ctiller): ordering constraint is here to match the ordering that
@ -253,7 +251,7 @@ void RegisterMessageSizeFilter(CoreConfiguration::Builder* builder) {
// filters from first principles.
.Before({&grpc_client_deadline_filter});
builder->channel_init()
->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerMessageSizeFilter::kFilter)
->RegisterFilter<ServerMessageSizeFilter>(GRPC_SERVER_CHANNEL)
.ExcludeFromMinimalStack()
.If(HasMessageSizeLimits)
// TODO(ctiller): ordering constraint is here to match the ordering that

@ -43,8 +43,14 @@
namespace grpc_core {
ArenaPromise<ServerMetadataHandle> RbacFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
const NoInterceptor RbacFilter::Call::OnServerInitialMetadata;
const NoInterceptor RbacFilter::Call::OnServerTrailingMetadata;
const NoInterceptor RbacFilter::Call::OnClientToServerMessage;
const NoInterceptor RbacFilter::Call::OnServerToClientMessage;
const NoInterceptor RbacFilter::Call::OnFinalize;
absl::Status RbacFilter::Call::OnClientInitialMetadata(ClientMetadata& md,
RbacFilter* filter) {
// Fetch and apply the rbac policy from the service config.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
GetContext<
@ -52,21 +58,19 @@ ArenaPromise<ServerMetadataHandle> RbacFilter::MakeCallPromise(
.value);
auto* method_params = static_cast<RbacMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(
service_config_parser_index_));
filter->service_config_parser_index_));
if (method_params == nullptr) {
return Immediate(ServerMetadataFromStatus(
absl::PermissionDeniedError("No RBAC policy found.")));
return absl::PermissionDeniedError("No RBAC policy found.");
} else {
auto* authorization_engine = method_params->authorization_engine(index_);
auto* authorization_engine =
method_params->authorization_engine(filter->index_);
if (authorization_engine
->Evaluate(EvaluateArgs(call_args.client_initial_metadata.get(),
&per_channel_evaluate_args_))
->Evaluate(EvaluateArgs(&md, &filter->per_channel_evaluate_args_))
.type == AuthorizationEngine::Decision::Type::kDeny) {
return Immediate(ServerMetadataFromStatus(
absl::PermissionDeniedError("Unauthorized RPC rejected")));
return absl::PermissionDeniedError("Unauthorized RPC rejected");
}
}
return next_promise_factory(std::move(call_args));
return absl::OkStatus();
}
const grpc_channel_filter RbacFilter::kFilterVtable =

@ -34,7 +34,7 @@ namespace grpc_core {
// Filter used when xDS server config fetcher provides a configuration with an
// HTTP RBAC filter. Also serves as the type for channel data for the filter.
class RbacFilter : public ChannelFilter {
class RbacFilter : public ImplementChannelFilter<RbacFilter> {
public:
// This channel filter is intended to be used by connections on xDS enabled
// servers configured with RBAC. The RBAC filter fetches the RBAC policy from
@ -45,9 +45,16 @@ class RbacFilter : public ChannelFilter {
static absl::StatusOr<RbacFilter> Create(const ChannelArgs& args,
ChannelFilter::Args filter_args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
absl::Status OnClientInitialMetadata(ClientMetadata& md,
RbacFilter* filter);
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
RbacFilter(size_t index,

@ -47,7 +47,8 @@ namespace grpc_core {
namespace {
class ServerConfigSelectorFilter final : public ChannelFilter {
class ServerConfigSelectorFilter final
: public ImplementChannelFilter<ServerConfigSelectorFilter> {
public:
~ServerConfigSelectorFilter() override;
@ -60,8 +61,16 @@ class ServerConfigSelectorFilter final : public ChannelFilter {
static absl::StatusOr<ServerConfigSelectorFilter> Create(
const ChannelArgs& args, ChannelFilter::Args);
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
absl::Status OnClientInitialMetadata(ClientMetadata& md,
ServerConfigSelectorFilter* filter);
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector() {
MutexLock lock(&state_->mu);
@ -130,25 +139,28 @@ ServerConfigSelectorFilter::~ServerConfigSelectorFilter() {
}
}
ArenaPromise<ServerMetadataHandle> ServerConfigSelectorFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
auto sel = config_selector();
if (!sel.ok()) return Immediate(ServerMetadataFromStatus(sel.status()));
auto call_config =
sel.value()->GetCallConfig(call_args.client_initial_metadata.get());
absl::Status ServerConfigSelectorFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, ServerConfigSelectorFilter* filter) {
auto sel = filter->config_selector();
if (!sel.ok()) return sel.status();
auto call_config = sel.value()->GetCallConfig(&md);
if (!call_config.ok()) {
auto r = Immediate(ServerMetadataFromStatus(
absl::UnavailableError(StatusToString(call_config.status()))));
return std::move(r);
return absl::UnavailableError(StatusToString(call_config.status()));
}
auto* service_config_call_data =
GetContext<Arena>()->New<ServiceConfigCallData>(
GetContext<Arena>(), GetContext<grpc_call_context_element>());
service_config_call_data->SetServiceConfig(
std::move(call_config->service_config), call_config->method_configs);
return next_promise_factory(std::move(call_args));
return absl::OkStatus();
}
const NoInterceptor ServerConfigSelectorFilter::Call::OnServerInitialMetadata;
const NoInterceptor ServerConfigSelectorFilter::Call::OnServerTrailingMetadata;
const NoInterceptor ServerConfigSelectorFilter::Call::OnClientToServerMessage;
const NoInterceptor ServerConfigSelectorFilter::Call::OnServerToClientMessage;
const NoInterceptor ServerConfigSelectorFilter::Call::OnFinalize;
} // namespace
const grpc_channel_filter kServerConfigSelectorFilter =

@ -58,6 +58,9 @@
namespace grpc_core {
TraceFlag grpc_stateful_session_filter_trace(false, "stateful_session_filter");
const NoInterceptor StatefulSessionFilter::Call::OnClientToServerMessage;
const NoInterceptor StatefulSessionFilter::Call::OnServerToClientMessage;
const NoInterceptor StatefulSessionFilter::Call::OnFinalize;
UniqueTypeName XdsOverrideHostAttribute::TypeName() {
static UniqueTypeName::Factory kFactory("xds_override_host");
@ -103,7 +106,7 @@ void MaybeUpdateServerInitialMetadata(
bool cluster_changed, absl::string_view actual_cluster,
absl::string_view cookie_address_list,
XdsOverrideHostAttribute* override_host_attribute,
ServerMetadata* server_initial_metadata) {
ServerMetadata& server_initial_metadata) {
// If cookie doesn't need to change, do nothing.
if (cookie_address_list == override_host_attribute->actual_address_list() &&
!cluster_changed) {
@ -121,7 +124,7 @@ void MaybeUpdateServerInitialMetadata(
parts.emplace_back(
absl::StrCat("Max-Age=", cookie_config->ttl.as_timespec().tv_sec));
}
server_initial_metadata->Append(
server_initial_metadata.Append(
"set-cookie", Slice::FromCopiedString(absl::StrJoin(parts, "; ")),
[](absl::string_view error, const Slice&) {
Crash(absl::StrCat("ERROR ADDING set-cookie METADATA: ", error));
@ -168,12 +171,11 @@ absl::string_view GetClusterToUse(
return absl::StripPrefix(arena_allocated_cluster, kClusterPrefix);
}
std::string GetCookieValue(const ClientMetadataHandle& client_initial_metadata,
std::string GetCookieValue(const ClientMetadata& client_initial_metadata,
absl::string_view cookie_name) {
// Check to see if the cookie header is present.
std::string buffer;
auto header_value =
client_initial_metadata->GetStringValue("cookie", &buffer);
auto header_value = client_initial_metadata.GetStringValue("cookie", &buffer);
if (!header_value.has_value()) return "";
// Parse cookie header.
std::vector<absl::string_view> values;
@ -193,13 +195,14 @@ std::string GetCookieValue(const ClientMetadataHandle& client_initial_metadata,
}
bool IsConfiguredPath(absl::string_view configured_path,
const ClientMetadataHandle& client_initial_metadata) {
const ClientMetadata& client_initial_metadata) {
// No path configured meaning all paths match
if (configured_path.empty()) {
return true;
}
// Check to see if the configured path matches the request path.
Slice* path_slice = client_initial_metadata->get_pointer(HttpPathMetadata());
const Slice* path_slice =
client_initial_metadata.get_pointer(HttpPathMetadata());
GPR_ASSERT(path_slice != nullptr);
absl::string_view path = path_slice->as_string_view();
// Matching criteria from
@ -218,9 +221,8 @@ bool IsConfiguredPath(absl::string_view configured_path,
}
} // namespace
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> StatefulSessionFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
void StatefulSessionFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, StatefulSessionFilter* filter) {
// Get config.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
GetContext<
@ -229,62 +231,57 @@ ArenaPromise<ServerMetadataHandle> StatefulSessionFilter::MakeCallPromise(
GPR_ASSERT(service_config_call_data != nullptr);
auto* method_params = static_cast<StatefulSessionMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(
service_config_parser_index_));
filter->service_config_parser_index_));
GPR_ASSERT(method_params != nullptr);
auto* cookie_config = method_params->GetConfig(index_);
GPR_ASSERT(cookie_config != nullptr);
if (!cookie_config->name.has_value() ||
!IsConfiguredPath(cookie_config->path,
call_args.client_initial_metadata)) {
return next_promise_factory(std::move(call_args));
cookie_config_ = method_params->GetConfig(filter->index_);
GPR_ASSERT(cookie_config_ != nullptr);
if (!cookie_config_->name.has_value() ||
!IsConfiguredPath(cookie_config_->path, md)) {
return;
}
// Base64-decode cookie value.
std::string cookie_value =
GetCookieValue(call_args.client_initial_metadata, *cookie_config->name);
std::string cookie_value = GetCookieValue(md, *cookie_config_->name);
// Cookie format is "host;cluster"
std::pair<absl::string_view, absl::string_view> host_cluster =
absl::StrSplit(cookie_value, absl::MaxSplits(';', 1));
absl::string_view cookie_address_list;
// Allocate the string on the arena, so that it has the right lifetime.
if (!host_cluster.first.empty()) {
cookie_address_list = AllocateStringOnArena(host_cluster.first);
cookie_address_list_ = AllocateStringOnArena(host_cluster.first);
}
// Set override host attribute.
auto* override_host_attribute =
override_host_attribute_ =
GetContext<Arena>()->ManagedNew<XdsOverrideHostAttribute>(
cookie_address_list);
service_config_call_data->SetCallAttribute(override_host_attribute);
cookie_address_list_);
service_config_call_data->SetCallAttribute(override_host_attribute_);
// Check if the cluster override is valid, and apply it if necessary.
// Note that cluster_name will point to an arena-allocated string
// that will still be alive when we see the server initial metadata.
// If the cluster name is empty, that means we cannot use a
// cluster override (i.e., the route uses a cluster specifier plugin).
absl::string_view cluster_name =
cluster_name_ =
GetClusterToUse(host_cluster.second, service_config_call_data);
bool cluster_changed = cluster_name != host_cluster.second;
// Intercept server initial metadata.
call_args.server_initial_metadata->InterceptAndMap(
[cookie_config, cluster_changed, cluster_name, cookie_address_list,
override_host_attribute](ServerMetadataHandle md) {
// Add cookie to server initial metadata if needed.
MaybeUpdateServerInitialMetadata(cookie_config, cluster_changed,
cluster_name, cookie_address_list,
override_host_attribute, md.get());
return md;
});
return Map(next_promise_factory(std::move(call_args)),
[cookie_config, cluster_changed, cluster_name, cookie_address_list,
override_host_attribute](ServerMetadataHandle md) {
// If we got a Trailers-Only response, then add the
// cookie to the trailing metadata instead of the
// initial metadata.
if (md->get(GrpcTrailersOnly()).value_or(false)) {
MaybeUpdateServerInitialMetadata(
cookie_config, cluster_changed, cluster_name,
cookie_address_list, override_host_attribute, md.get());
}
return md;
});
cluster_changed_ = cluster_name_ != host_cluster.second;
perform_filtering_ = true;
}
void StatefulSessionFilter::Call::OnServerInitialMetadata(ServerMetadata& md) {
if (!perform_filtering_) return;
// Add cookie to server initial metadata if needed.
MaybeUpdateServerInitialMetadata(cookie_config_, cluster_changed_,
cluster_name_, cookie_address_list_,
override_host_attribute_, md);
}
void StatefulSessionFilter::Call::OnServerTrailingMetadata(ServerMetadata& md) {
if (!perform_filtering_) return;
// If we got a Trailers-Only response, then add the
// cookie to the trailing metadata instead of the
// initial metadata.
if (md.get(GrpcTrailersOnly()).value_or(false)) {
MaybeUpdateServerInitialMetadata(cookie_config_, cluster_changed_,
cluster_name_, cookie_address_list_,
override_host_attribute_, md);
}
}
void StatefulSessionFilterRegister(CoreConfiguration::Builder* builder) {

@ -26,6 +26,7 @@
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_fwd.h"
#include "src/core/lib/channel/promise_based_filter.h"
@ -68,16 +69,32 @@ class XdsOverrideHostAttribute
};
// A filter to provide cookie-based stateful session affinity.
class StatefulSessionFilter : public ChannelFilter {
class StatefulSessionFilter
: public ImplementChannelFilter<StatefulSessionFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<StatefulSessionFilter> Create(
const ChannelArgs& args, ChannelFilter::Args filter_args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
class Call {
public:
void OnClientInitialMetadata(ClientMetadata& md,
StatefulSessionFilter* filter);
void OnServerInitialMetadata(ServerMetadata& md);
void OnServerTrailingMetadata(ServerMetadata& md);
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
private:
const StatefulSessionMethodParsedConfig::CookieConfig* cookie_config_;
XdsOverrideHostAttribute* override_host_attribute_;
absl::string_view cluster_name_;
absl::string_view cookie_address_list_;
bool cluster_changed_;
bool perform_filtering_ = false;
};
private:
explicit StatefulSessionFilter(ChannelFilter::Args filter_args);

@ -0,0 +1,19 @@
// Copyright 2023 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 <grpc/support/port_platform.h>
#include "src/core/ext/transport/chaotic_good/chaotic_good_transport.h"
namespace grpc_core {} // namespace grpc_core

@ -0,0 +1,111 @@
// Copyright 2023 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_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_CHAOTIC_GOOD_TRANSPORT_H
#define GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_CHAOTIC_GOOD_TRANSPORT_H
#include <grpc/support/port_platform.h>
#include "absl/random/random.h"
#include "src/core/ext/transport/chaotic_good/frame.h"
#include "src/core/ext/transport/chaotic_good/frame_header.h"
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/lib/promise/if.h"
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/try_join.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/transport/promise_endpoint.h"
namespace grpc_core {
namespace chaotic_good {
class ChaoticGoodTransport {
public:
ChaoticGoodTransport(std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint)
: control_endpoint_(std::move(control_endpoint)),
data_endpoint_(std::move(data_endpoint)) {}
auto WriteFrame(const FrameInterface& frame) {
auto buffers = frame.Serialize(&encoder_);
return TryJoin<absl::StatusOr>(
control_endpoint_->Write(std::move(buffers.control)),
data_endpoint_->Write(std::move(buffers.data)));
}
// Read frame header and payloads for control and data portions of one frame.
// Resolves to StatusOr<tuple<FrameHeader, BufferPair>>.
auto ReadFrameBytes() {
return TrySeq(
control_endpoint_->ReadSlice(FrameHeader::frame_header_size_),
[this](Slice read_buffer) {
auto frame_header =
FrameHeader::Parse(reinterpret_cast<const uint8_t*>(
GRPC_SLICE_START_PTR(read_buffer.c_slice())));
// Read header and trailers from control endpoint.
// Read message padding and message from data endpoint.
return If(
frame_header.ok(),
[this, &frame_header] {
const uint32_t message_padding = std::exchange(
last_message_padding_, frame_header->message_padding);
const uint32_t message_length = frame_header->message_length;
return Map(
TryJoin<absl::StatusOr>(
control_endpoint_->Read(frame_header->GetFrameLength()),
TrySeq(data_endpoint_->Read(message_padding),
[this, message_length]() {
return data_endpoint_->Read(message_length);
})),
[frame_header = *frame_header](
absl::StatusOr<std::tuple<SliceBuffer, SliceBuffer>>
buffers)
-> absl::StatusOr<std::tuple<FrameHeader, BufferPair>> {
if (!buffers.ok()) return buffers.status();
return std::tuple<FrameHeader, BufferPair>(
frame_header,
BufferPair{std::move(std::get<0>(*buffers)),
std::move(std::get<1>(*buffers))});
});
},
[&frame_header]()
-> absl::StatusOr<std::tuple<FrameHeader, BufferPair>> {
return frame_header.status();
});
});
}
absl::Status DeserializeFrame(FrameHeader header, BufferPair buffers,
Arena* arena, FrameInterface& frame) {
return frame.Deserialize(&parser_, header, bitgen_, arena,
std::move(buffers));
}
// Skip a frame, but correctly handle any hpack state updates.
void SkipFrame(FrameHeader, BufferPair) { Crash("not implemented"); }
private:
const std::unique_ptr<PromiseEndpoint> control_endpoint_;
const std::unique_ptr<PromiseEndpoint> data_endpoint_;
uint32_t last_message_padding_ = 0;
HPackCompressor encoder_;
HPackParser parser_;
absl::BitGen bitgen_;
};
} // namespace chaotic_good
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_CHAOTIC_GOOD_TRANSPORT_H

@ -17,9 +17,11 @@
#include "src/core/ext/transport/chaotic_good/client_transport.h"
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include "absl/random/bit_gen_ref.h"
#include "absl/random/random.h"
@ -36,9 +38,13 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/all_ok.h"
#include "src/core/lib/promise/event_engine_wakeup_scheduler.h"
#include "src/core/lib/promise/loop.h"
#include "src/core/lib/promise/map.h"
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/try_join.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/resource_quota/resource_quota.h"
#include "src/core/lib/slice/slice.h"
@ -49,59 +55,15 @@
namespace grpc_core {
namespace chaotic_good {
ClientTransport::ClientTransport(
std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint,
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine)
: outgoing_frames_(MpscReceiver<ClientFrame>(4)),
control_endpoint_(std::move(control_endpoint)),
data_endpoint_(std::move(data_endpoint)),
control_endpoint_write_buffer_(SliceBuffer()),
data_endpoint_write_buffer_(SliceBuffer()),
hpack_compressor_(std::make_unique<HPackCompressor>()),
hpack_parser_(std::make_unique<HPackParser>()),
memory_allocator_(
ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator(
"client_transport")),
arena_(MakeScopedArena(1024, &memory_allocator_)),
context_(arena_.get()),
event_engine_(event_engine) {
auto write_loop = Loop([this] {
auto ChaoticGoodClientTransport::TransportWriteLoop() {
return Loop([this] {
return TrySeq(
// Get next outgoing frame.
this->outgoing_frames_.Next(),
// Construct data buffers that will be sent to the endpoints.
outgoing_frames_.Next(),
// Serialize and write it out.
[this](ClientFrame client_frame) {
MatchMutable(
&client_frame,
[this](ClientFragmentFrame* frame) mutable {
control_endpoint_write_buffer_.Append(
frame->Serialize(hpack_compressor_.get()));
if (frame->message != nullptr) {
std::string message_padding(frame->message_padding, '0');
Slice slice(grpc_slice_from_cpp_string(message_padding));
// Append message padding to data_endpoint_buffer.
data_endpoint_write_buffer_.Append(std::move(slice));
// Append message payload to data_endpoint_buffer.
frame->message->payload()->MoveFirstNBytesIntoSliceBuffer(
frame->message->payload()->Length(),
data_endpoint_write_buffer_);
}
},
[this](CancelFrame* frame) mutable {
control_endpoint_write_buffer_.Append(
frame->Serialize(hpack_compressor_.get()));
});
return absl::OkStatus();
return transport_.WriteFrame(GetFrameInterface(client_frame));
},
// Write buffers to corresponding endpoints concurrently.
[this]() {
return TryJoin<absl::StatusOr>(
control_endpoint_->Write(
std::move(control_endpoint_write_buffer_)),
data_endpoint_->Write(std::move(data_endpoint_write_buffer_)));
},
// Finish writes to difference endpoints and continue the loop.
[]() -> LoopCtl<absl::Status> {
// The write failures will be caught in TrySeq and exit loop.
// Therefore, only need to return Continue() in the last lambda
@ -109,78 +71,215 @@ ClientTransport::ClientTransport(
return Continue();
});
});
writer_ = MakeActivity(
// Continuously write next outgoing frames to promise endpoints.
std::move(write_loop), EventEngineWakeupScheduler(event_engine_),
[this](absl::Status status) {
if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) {
this->AbortWithError();
}
}
absl::optional<CallHandler> ChaoticGoodClientTransport::LookupStream(
uint32_t stream_id) {
MutexLock lock(&mu_);
auto it = stream_map_.find(stream_id);
if (it == stream_map_.end()) {
return absl::nullopt;
}
return it->second;
}
auto ChaoticGoodClientTransport::PushFrameIntoCall(ServerFragmentFrame frame,
CallHandler call_handler) {
auto& headers = frame.headers;
return TrySeq(
If(
headers != nullptr,
[call_handler, &headers]() mutable {
return call_handler.PushServerInitialMetadata(std::move(headers));
},
[]() -> StatusFlag { return Success{}; }),
[call_handler, message = std::move(frame.message)]() mutable {
return If(
message.has_value(),
[&call_handler, &message]() mutable {
return call_handler.PushMessage(std::move(message->message));
},
[]() -> StatusFlag { return Success{}; });
},
// Hold Arena in activity for GetContext<Arena> usage.
arena_.get());
auto read_loop = Loop([this] {
[call_handler, trailers = std::move(frame.trailers)]() mutable {
return If(
trailers != nullptr,
[&call_handler, &trailers]() mutable {
return call_handler.PushServerTrailingMetadata(
std::move(trailers));
},
[]() -> StatusFlag { return Success{}; });
});
}
auto ChaoticGoodClientTransport::TransportReadLoop() {
return Loop([this] {
return TrySeq(
// Read frame header from control endpoint.
// TODO(ladynana): remove memcpy in ReadSlice.
this->control_endpoint_->ReadSlice(FrameHeader::frame_header_size_),
// Read different parts of the server frame from control/data endpoints
// based on frame header.
[this](Slice read_buffer) mutable {
frame_header_ = std::make_shared<FrameHeader>(
FrameHeader::Parse(
reinterpret_cast<const uint8_t*>(
GRPC_SLICE_START_PTR(read_buffer.c_slice())))
.value());
// Read header and trailers from control endpoint.
// Read message padding and message from data endpoint.
return TryJoin<absl::StatusOr>(
control_endpoint_->Read(frame_header_->GetFrameLength()),
data_endpoint_->Read(frame_header_->message_padding +
frame_header_->message_length));
transport_.ReadFrameBytes(),
[](std::tuple<FrameHeader, BufferPair> frame_bytes)
-> absl::StatusOr<std::tuple<FrameHeader, BufferPair>> {
const auto& frame_header = std::get<0>(frame_bytes);
if (frame_header.type != FrameType::kFragment) {
return absl::InternalError(
absl::StrCat("Expected fragment frame, got ",
static_cast<int>(frame_header.type)));
}
return frame_bytes;
},
// Construct and send the server frame to corresponding stream.
[this](std::tuple<SliceBuffer, SliceBuffer> ret) mutable {
control_endpoint_read_buffer_ = std::move(std::get<0>(ret));
// Discard message padding and only keep message in data read buffer.
std::get<1>(ret).MoveLastNBytesIntoSliceBuffer(
frame_header_->message_length, data_endpoint_read_buffer_);
[this](std::tuple<FrameHeader, BufferPair> frame_bytes) {
const auto& frame_header = std::get<0>(frame_bytes);
auto& buffers = std::get<1>(frame_bytes);
absl::optional<CallHandler> call_handler =
LookupStream(frame_header.stream_id);
ServerFragmentFrame frame;
// Initialized to get this_cpu() info in global_stat().
ExecCtx exec_ctx;
// Deserialize frame from read buffer.
absl::BitGen bitgen;
auto status = frame.Deserialize(hpack_parser_.get(), *frame_header_,
absl::BitGenRef(bitgen),
control_endpoint_read_buffer_);
GPR_ASSERT(status.ok());
// Move message into frame.
frame.message = arena_->MakePooled<Message>(
std::move(data_endpoint_read_buffer_), 0);
MutexLock lock(&mu_);
const uint32_t stream_id = frame_header_->stream_id;
return stream_map_[stream_id]->Push(ServerFrame(std::move(frame)));
},
// Check if send frame to corresponding stream successfully.
[](bool ret) -> LoopCtl<absl::Status> {
if (ret) {
// Send incoming frames successfully.
return Continue();
absl::Status deserialize_status;
if (call_handler.has_value()) {
deserialize_status = transport_.DeserializeFrame(
frame_header, std::move(buffers), call_handler->arena(), frame);
} else {
return absl::InternalError("Send incoming frames failed.");
// Stream not found, skip the frame.
transport_.SkipFrame(frame_header, std::move(buffers));
deserialize_status = absl::OkStatus();
}
});
return If(
deserialize_status.ok() && call_handler.has_value(),
[this, &frame, &call_handler]() {
return call_handler->SpawnWaitable(
"push-frame", [this, call_handler = *call_handler,
frame = std::move(frame)]() mutable {
return Map(call_handler.CancelIfFails(PushFrameIntoCall(
std::move(frame), call_handler)),
[](StatusFlag f) {
return StatusCast<absl::Status>(f);
});
});
},
[&deserialize_status]() -> absl::Status {
// Stream not found, nothing to do.
return std::move(deserialize_status);
});
},
[]() -> LoopCtl<absl::Status> { return Continue{}; });
});
reader_ = MakeActivity(
// Continuously read next incoming frames from promise endpoints.
std::move(read_loop), EventEngineWakeupScheduler(event_engine_),
[this](absl::Status status) {
if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) {
this->AbortWithError();
}
}
auto ChaoticGoodClientTransport::OnTransportActivityDone() {
return [this](absl::Status status) {
if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) {
this->AbortWithError();
}
};
}
ChaoticGoodClientTransport::ChaoticGoodClientTransport(
std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint,
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine)
: outgoing_frames_(4),
transport_(std::move(control_endpoint), std::move(data_endpoint)),
writer_{
MakeActivity(
// Continuously write next outgoing frames to promise endpoints.
TransportWriteLoop(), EventEngineWakeupScheduler(event_engine),
OnTransportActivityDone()),
},
reader_{MakeActivity(
// Continuously read next incoming frames from promise endpoints.
TransportReadLoop(), EventEngineWakeupScheduler(event_engine),
OnTransportActivityDone())} {}
ChaoticGoodClientTransport::~ChaoticGoodClientTransport() {
if (writer_ != nullptr) {
writer_.reset();
}
if (reader_ != nullptr) {
reader_.reset();
}
}
void ChaoticGoodClientTransport::AbortWithError() {
// Mark transport as unavailable when the endpoint write/read failed.
// Close all the available pipes.
outgoing_frames_.MarkClosed();
ReleasableMutexLock lock(&mu_);
StreamMap stream_map = std::move(stream_map_);
stream_map_.clear();
lock.Release();
for (const auto& pair : stream_map) {
auto call_handler = pair.second;
call_handler.SpawnInfallible("cancel", [call_handler]() mutable {
call_handler.Cancel(ServerMetadataFromStatus(
absl::UnavailableError("Transport closed.")));
return Empty{};
});
}
}
uint32_t ChaoticGoodClientTransport::MakeStream(CallHandler call_handler) {
ReleasableMutexLock lock(&mu_);
const uint32_t stream_id = next_stream_id_++;
stream_map_.emplace(stream_id, call_handler);
lock.Release();
call_handler.OnDone([this, stream_id]() {
MutexLock lock(&mu_);
stream_map_.erase(stream_id);
});
return stream_id;
}
auto ChaoticGoodClientTransport::CallOutboundLoop(uint32_t stream_id,
CallHandler call_handler) {
auto send_fragment = [stream_id,
outgoing_frames = outgoing_frames_.MakeSender()](
ClientFragmentFrame frame) mutable {
frame.stream_id = stream_id;
return Map(outgoing_frames.Send(std::move(frame)),
[](bool success) -> absl::Status {
if (!success) {
// Failed to send outgoing frame.
return absl::UnavailableError("Transport closed.");
}
return absl::OkStatus();
});
};
return TrySeq(
// Wait for initial metadata then send it out.
call_handler.PullClientInitialMetadata(),
[send_fragment](ClientMetadataHandle md) mutable {
ClientFragmentFrame frame;
frame.headers = std::move(md);
return send_fragment(std::move(frame));
},
// Hold Arena in activity for GetContext<Arena> usage.
arena_.get());
// Continuously send client frame with client to server messages.
ForEach(OutgoingMessages(call_handler),
[send_fragment,
aligned_bytes = aligned_bytes_](MessageHandle message) mutable {
ClientFragmentFrame frame;
// Construct frame header (flags, header_length and
// trailer_length will be added in serialization).
const uint32_t message_length = message->payload()->Length();
const uint32_t padding =
message_length % aligned_bytes == 0
? 0
: aligned_bytes - message_length % aligned_bytes;
GPR_ASSERT((message_length + padding) % aligned_bytes == 0);
frame.message = FragmentMessage(std::move(message), padding,
message_length);
return send_fragment(std::move(frame));
}),
[send_fragment]() mutable {
ClientFragmentFrame frame;
frame.end_of_stream = true;
return send_fragment(std::move(frame));
});
}
void ChaoticGoodClientTransport::StartCall(CallHandler call_handler) {
// At this point, the connection is set up.
// Start sending data frames.
call_handler.SpawnGuarded("outbound_loop", [this, call_handler]() mutable {
return CallOutboundLoop(MakeStream(call_handler), call_handler);
});
}
} // namespace chaotic_good

@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdio.h>
#include <cstdint>
#include <initializer_list> // IWYU pragma: keep
#include <map>
#include <memory>
@ -28,6 +29,8 @@
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/random/random.h"
#include "absl/status/status.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
@ -35,6 +38,7 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/event_engine/memory_allocator.h>
#include "src/core/ext/transport/chaotic_good/chaotic_good_transport.h"
#include "src/core/ext/transport/chaotic_good/frame.h"
#include "src/core/ext/transport/chaotic_good/frame_header.h"
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
@ -61,178 +65,56 @@
namespace grpc_core {
namespace chaotic_good {
class ClientTransport {
class ChaoticGoodClientTransport final : public Transport,
public ClientTransport {
public:
ClientTransport(std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine);
~ClientTransport() {
if (writer_ != nullptr) {
writer_.reset();
}
if (reader_ != nullptr) {
reader_.reset();
}
}
void AbortWithError() {
// Mark transport as unavailable when the endpoint write/read failed.
// Close all the available pipes.
if (!outgoing_frames_.IsClosed()) {
outgoing_frames_.MarkClosed();
}
MutexLock lock(&mu_);
for (const auto& pair : stream_map_) {
if (!pair.second->IsClose()) {
pair.second->MarkClose();
}
}
}
auto AddStream(CallArgs call_args) {
// At this point, the connection is set up.
// Start sending data frames.
uint32_t stream_id;
InterActivityPipe<ServerFrame, server_frame_queue_size_> pipe_server_frames;
{
MutexLock lock(&mu_);
stream_id = next_stream_id_++;
stream_map_.insert(
std::pair<uint32_t,
std::shared_ptr<InterActivityPipe<
ServerFrame, server_frame_queue_size_>::Sender>>(
stream_id, std::make_shared<InterActivityPipe<
ServerFrame, server_frame_queue_size_>::Sender>(
std::move(pipe_server_frames.sender))));
}
return TrySeq(
TryJoin<absl::StatusOr>(
// Continuously send client frame with client to server messages.
ForEach(std::move(*call_args.client_to_server_messages),
[stream_id, initial_frame = true,
client_initial_metadata =
std::move(call_args.client_initial_metadata),
outgoing_frames = outgoing_frames_.MakeSender(),
this](MessageHandle result) mutable {
ClientFragmentFrame frame;
// Construct frame header (flags, header_length and
// trailer_length will be added in serialization).
uint32_t message_length = result->payload()->Length();
frame.stream_id = stream_id;
frame.message_padding = message_length % aligned_bytes;
frame.message = std::move(result);
if (initial_frame) {
// Send initial frame with client intial metadata.
frame.headers = std::move(client_initial_metadata);
initial_frame = false;
}
return TrySeq(
outgoing_frames.Send(ClientFrame(std::move(frame))),
[](bool success) -> absl::Status {
if (!success) {
// TODO(ladynana): propagate the actual error
// message from EventEngine.
return absl::UnavailableError(
"Transport closed due to endpoint write/read "
"failed.");
}
return absl::OkStatus();
});
}),
// Continuously receive server frames from endpoints and save
// results to call_args.
Loop([server_initial_metadata = call_args.server_initial_metadata,
server_to_client_messages =
call_args.server_to_client_messages,
receiver = std::move(pipe_server_frames.receiver)]() mutable {
return TrySeq(
// Receive incoming server frame.
receiver.Next(),
// Save incomming frame results to call_args.
[server_initial_metadata, server_to_client_messages](
absl::optional<ServerFrame> server_frame) mutable {
bool transport_closed = false;
ServerFragmentFrame frame;
if (!server_frame.has_value()) {
// Incoming server frame pipe is closed, which only
// happens when transport is aborted.
transport_closed = true;
} else {
frame = std::move(
absl::get<ServerFragmentFrame>(*server_frame));
};
bool has_headers = (frame.headers != nullptr);
bool has_message = (frame.message != nullptr);
bool has_trailers = (frame.trailers != nullptr);
return TrySeq(
If((!transport_closed) && has_headers,
[server_initial_metadata,
headers = std::move(frame.headers)]() mutable {
return server_initial_metadata->Push(
std::move(headers));
},
[] { return false; }),
If((!transport_closed) && has_message,
[server_to_client_messages,
message = std::move(frame.message)]() mutable {
return server_to_client_messages->Push(
std::move(message));
},
[] { return false; }),
If((!transport_closed) && has_trailers,
[trailers = std::move(frame.trailers)]() mutable
-> LoopCtl<ServerMetadataHandle> {
return std::move(trailers);
},
[transport_closed]()
-> LoopCtl<ServerMetadataHandle> {
if (transport_closed) {
// TODO(ladynana): propagate the actual error
// message from EventEngine.
return ServerMetadataFromStatus(
absl::UnavailableError(
"Transport closed due to endpoint "
"write/read failed."));
}
return Continue();
}));
});
})),
[](std::tuple<Empty, ServerMetadataHandle> ret) {
return std::move(std::get<1>(ret));
});
}
ChaoticGoodClientTransport(
std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine);
~ChaoticGoodClientTransport() override;
FilterStackTransport* filter_stack_transport() override { return nullptr; }
ClientTransport* client_transport() override { return this; }
ServerTransport* server_transport() override { return nullptr; }
absl::string_view GetTransportName() const override { return "chaotic_good"; }
void SetPollset(grpc_stream*, grpc_pollset*) override {}
void SetPollsetSet(grpc_stream*, grpc_pollset_set*) override {}
void PerformOp(grpc_transport_op*) override { Crash("unimplemented"); }
grpc_endpoint* GetEndpoint() override { return nullptr; }
void Orphan() override { delete this; }
void StartCall(CallHandler call_handler) override;
void AbortWithError();
private:
// Queue size of each stream pipe is set to 2, so that for each stream read it
// will queue at most 2 frames.
static const size_t kServerFrameQueueSize = 2;
using StreamMap = absl::flat_hash_map<uint32_t, CallHandler>;
uint32_t MakeStream(CallHandler call_handler);
absl::optional<CallHandler> LookupStream(uint32_t stream_id);
auto CallOutboundLoop(uint32_t stream_id, CallHandler call_handler);
auto OnTransportActivityDone();
auto TransportWriteLoop();
auto TransportReadLoop();
// Push one frame into a call
auto PushFrameIntoCall(ServerFragmentFrame frame, CallHandler call_handler);
// Max buffer is set to 4, so that for stream writes each time it will queue
// at most 2 frames.
MpscReceiver<ClientFrame> outgoing_frames_;
// Queue size of each stream pipe is set to 2, so that for each stream read it
// will queue at most 2 frames.
static const size_t server_frame_queue_size_ = 2;
ChaoticGoodTransport transport_;
// Assigned aligned bytes from setting frame.
size_t aligned_bytes = 64;
size_t aligned_bytes_ = 64;
Mutex mu_;
uint32_t next_stream_id_ ABSL_GUARDED_BY(mu_) = 1;
// Map of stream incoming server frames, key is stream_id.
std::map<uint32_t, std::shared_ptr<InterActivityPipe<
ServerFrame, server_frame_queue_size_>::Sender>>
stream_map_ ABSL_GUARDED_BY(mu_);
StreamMap stream_map_ ABSL_GUARDED_BY(mu_);
ActivityPtr writer_;
ActivityPtr reader_;
std::unique_ptr<PromiseEndpoint> control_endpoint_;
std::unique_ptr<PromiseEndpoint> data_endpoint_;
SliceBuffer control_endpoint_write_buffer_;
SliceBuffer data_endpoint_write_buffer_;
SliceBuffer control_endpoint_read_buffer_;
SliceBuffer data_endpoint_read_buffer_;
std::unique_ptr<HPackCompressor> hpack_compressor_;
std::unique_ptr<HPackParser> hpack_parser_;
std::shared_ptr<FrameHeader> frame_header_;
MemoryAllocator memory_allocator_;
ScopedArenaPtr arena_;
promise_detail::Context<Arena> context_;
// Use to synchronize writer_ and reader_ activity with outside activities;
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_;
};
} // namespace chaotic_good

@ -40,6 +40,10 @@
namespace grpc_core {
namespace chaotic_good {
namespace {
const uint8_t kZeros[64] = {};
}
namespace {
const NoDestruct<Slice> kZeroSlice{[] {
// Frame header size is fixed to 24 bytes.
@ -50,53 +54,65 @@ const NoDestruct<Slice> kZeroSlice{[] {
class FrameSerializer {
public:
explicit FrameSerializer(FrameType frame_type, uint32_t stream_id,
uint32_t message_padding) {
output_.AppendIndexed(kZeroSlice->Copy());
explicit FrameSerializer(FrameType frame_type, uint32_t stream_id) {
output_.control.AppendIndexed(kZeroSlice->Copy());
header_.type = frame_type;
header_.stream_id = stream_id;
header_.message_padding = message_padding;
header_.flags.SetAll(false);
}
// If called, must be called before AddTrailers, Finish.
SliceBuffer& AddHeaders() {
header_.flags.set(0);
return output_;
return output_.control;
}
void AddMessage(const FragmentMessage& msg) {
header_.flags.set(1);
header_.message_length = msg.length;
header_.message_padding = msg.padding;
output_.data = msg.message->payload()->Copy();
if (msg.padding != 0) {
output_.data.Append(Slice::FromStaticBuffer(kZeros, msg.padding));
}
}
// If called, must be called before Finish.
SliceBuffer& AddTrailers() {
header_.flags.set(1);
header_.header_length = output_.Length() - FrameHeader::frame_header_size_;
return output_;
header_.flags.set(2);
header_.header_length =
output_.control.Length() - FrameHeader::frame_header_size_;
return output_.control;
}
SliceBuffer Finish() {
BufferPair Finish() {
// Calculate frame header_length or trailer_length if available.
if (header_.flags.is_set(1)) {
if (header_.flags.is_set(2)) {
// Header length is already known in AddTrailers().
header_.trailer_length = output_.Length() - header_.header_length -
header_.trailer_length = output_.control.Length() -
header_.header_length -
FrameHeader::frame_header_size_;
} else {
if (header_.flags.is_set(0)) {
// Calculate frame header length in Finish() since AddTrailers() isn't
// called.
header_.header_length =
output_.Length() - FrameHeader::frame_header_size_;
output_.control.Length() - FrameHeader::frame_header_size_;
}
}
header_.Serialize(
GRPC_SLICE_START_PTR(output_.c_slice_buffer()->slices[0]));
GRPC_SLICE_START_PTR(output_.control.c_slice_buffer()->slices[0]));
return std::move(output_);
}
private:
FrameHeader header_;
SliceBuffer output_;
BufferPair output_;
};
class FrameDeserializer {
public:
FrameDeserializer(const FrameHeader& header, SliceBuffer& input)
FrameDeserializer(const FrameHeader& header, BufferPair& input)
: header_(header), input_(input) {}
const FrameHeader& header() const { return header_; }
// If called, must be called before ReceiveTrailers, Finish.
@ -118,28 +134,27 @@ class FrameDeserializer {
private:
absl::StatusOr<SliceBuffer> Take(uint32_t length) {
if (length == 0) return SliceBuffer{};
if (input_.Length() < length) {
if (input_.control.Length() < length) {
return absl::InvalidArgumentError(
"Frame too short (insufficient payload)");
}
SliceBuffer out;
input_.MoveFirstNBytesIntoSliceBuffer(length, out);
input_.control.MoveFirstNBytesIntoSliceBuffer(length, out);
return std::move(out);
}
FrameHeader header_;
SliceBuffer& input_;
BufferPair& input_;
};
template <typename Metadata>
absl::StatusOr<Arena::PoolPtr<Metadata>> ReadMetadata(
HPackParser* parser, absl::StatusOr<SliceBuffer> maybe_slices,
uint32_t stream_id, bool is_header, bool is_client,
absl::BitGenRef bitsrc) {
uint32_t stream_id, bool is_header, bool is_client, absl::BitGenRef bitsrc,
Arena* arena) {
if (!maybe_slices.ok()) return maybe_slices.status();
auto& slices = *maybe_slices;
auto arena = GetContext<Arena>();
GPR_ASSERT(arena != nullptr);
Arena::PoolPtr<Metadata> metadata = arena->MakePooled<Metadata>(arena);
Arena::PoolPtr<Metadata> metadata = Arena::MakePooled<Metadata>(arena);
parser->BeginFrame(
metadata.get(), std::numeric_limits<uint32_t>::max(),
std::numeric_limits<uint32_t>::max(),
@ -161,20 +176,23 @@ absl::StatusOr<Arena::PoolPtr<Metadata>> ReadMetadata(
} // namespace
absl::Status SettingsFrame::Deserialize(HPackParser*, const FrameHeader& header,
absl::BitGenRef,
SliceBuffer& slice_buffer) {
absl::BitGenRef, Arena*,
BufferPair buffers) {
if (header.type != FrameType::kSettings) {
return absl::InvalidArgumentError("Expected settings frame");
}
if (header.flags.any()) {
return absl::InvalidArgumentError("Unexpected flags");
}
FrameDeserializer deserializer(header, slice_buffer);
if (buffers.data.Length() != 0) {
return absl::InvalidArgumentError("Unexpected data");
}
FrameDeserializer deserializer(header, buffers);
return deserializer.Finish();
}
SliceBuffer SettingsFrame::Serialize(HPackCompressor*) const {
FrameSerializer serializer(FrameType::kSettings, 0, 0);
BufferPair SettingsFrame::Serialize(HPackCompressor*) const {
FrameSerializer serializer(FrameType::kSettings, 0);
return serializer.Finish();
}
@ -183,19 +201,20 @@ std::string SettingsFrame::ToString() const { return "SettingsFrame{}"; }
absl::Status ClientFragmentFrame::Deserialize(HPackParser* parser,
const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) {
Arena* arena,
BufferPair buffers) {
if (header.stream_id == 0) {
return absl::InvalidArgumentError("Expected non-zero stream id");
}
stream_id = header.stream_id;
message_padding = header.message_padding;
if (header.type != FrameType::kFragment) {
return absl::InvalidArgumentError("Expected fragment frame");
}
FrameDeserializer deserializer(header, slice_buffer);
FrameDeserializer deserializer(header, buffers);
if (header.flags.is_set(0)) {
auto r = ReadMetadata<ClientMetadata>(parser, deserializer.ReceiveHeaders(),
header.stream_id, true, true, bitsrc);
header.stream_id, true, true, bitsrc,
arena);
if (!r.ok()) return r.status();
if (r.value() != nullptr) {
headers = std::move(r.value());
@ -205,8 +224,17 @@ absl::Status ClientFragmentFrame::Deserialize(HPackParser* parser,
"Unexpected non-zero header length", header.header_length));
}
if (header.flags.is_set(1)) {
message =
FragmentMessage{Arena::MakePooled<Message>(std::move(buffers.data), 0),
header.message_padding, header.message_length};
} else if (buffers.data.Length() != 0) {
return absl::InvalidArgumentError(absl::StrCat(
"Unexpected non-zero message length ", buffers.data.Length()));
}
if (header.flags.is_set(2)) {
if (header.trailer_length != 0) {
return absl::InvalidArgumentError("Unexpected trailer length");
return absl::InvalidArgumentError(
absl::StrCat("Unexpected trailer length ", header.trailer_length));
}
end_of_stream = true;
} else {
@ -215,42 +243,53 @@ absl::Status ClientFragmentFrame::Deserialize(HPackParser* parser,
return deserializer.Finish();
}
SliceBuffer ClientFragmentFrame::Serialize(HPackCompressor* encoder) const {
BufferPair ClientFragmentFrame::Serialize(HPackCompressor* encoder) const {
GPR_ASSERT(stream_id != 0);
FrameSerializer serializer(FrameType::kFragment, stream_id, message_padding);
FrameSerializer serializer(FrameType::kFragment, stream_id);
if (headers.get() != nullptr) {
encoder->EncodeRawHeaders(*headers.get(), serializer.AddHeaders());
}
if (message.has_value()) {
serializer.AddMessage(message.value());
}
if (end_of_stream) {
serializer.AddTrailers();
}
return serializer.Finish();
}
std::string FragmentMessage::ToString() const {
std::string out =
absl::StrCat("FragmentMessage{length=", length, ", padding=", padding);
if (message.get() != nullptr) {
absl::StrAppend(&out, ", message=", message->DebugString().c_str());
}
absl::StrAppend(&out, "}");
return out;
}
std::string ClientFragmentFrame::ToString() const {
return absl::StrCat(
"ClientFragmentFrame{stream_id=", stream_id, ", headers=",
headers.get() != nullptr ? headers->DebugString().c_str() : "nullptr",
", message=",
message.get() != nullptr ? message->DebugString().c_str() : "nullptr",
", message_padding=", message_padding, ", end_of_stream=", end_of_stream,
"}");
", message=", message.has_value() ? message->ToString().c_str() : "none",
", end_of_stream=", end_of_stream, "}");
}
absl::Status ServerFragmentFrame::Deserialize(HPackParser* parser,
const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) {
Arena* arena,
BufferPair buffers) {
if (header.stream_id == 0) {
return absl::InvalidArgumentError("Expected non-zero stream id");
}
stream_id = header.stream_id;
message_padding = header.message_padding;
FrameDeserializer deserializer(header, slice_buffer);
FrameDeserializer deserializer(header, buffers);
if (header.flags.is_set(0)) {
auto r =
ReadMetadata<ServerMetadata>(parser, deserializer.ReceiveHeaders(),
header.stream_id, true, false, bitsrc);
auto r = ReadMetadata<ServerMetadata>(parser, deserializer.ReceiveHeaders(),
header.stream_id, true, false, bitsrc,
arena);
if (!r.ok()) return r.status();
if (r.value() != nullptr) {
headers = std::move(r.value());
@ -260,9 +299,16 @@ absl::Status ServerFragmentFrame::Deserialize(HPackParser* parser,
"Unexpected non-zero header length", header.header_length));
}
if (header.flags.is_set(1)) {
auto r =
ReadMetadata<ServerMetadata>(parser, deserializer.ReceiveTrailers(),
header.stream_id, false, false, bitsrc);
message.emplace(Arena::MakePooled<Message>(std::move(buffers.data), 0),
header.message_padding, header.message_length);
} else if (buffers.data.Length() != 0) {
return absl::InvalidArgumentError(absl::StrCat(
"Unexpected non-zero message length", buffers.data.Length()));
}
if (header.flags.is_set(2)) {
auto r = ReadMetadata<ServerMetadata>(
parser, deserializer.ReceiveTrailers(), header.stream_id, false, false,
bitsrc, arena);
if (!r.ok()) return r.status();
if (r.value() != nullptr) {
trailers = std::move(r.value());
@ -274,12 +320,15 @@ absl::Status ServerFragmentFrame::Deserialize(HPackParser* parser,
return deserializer.Finish();
}
SliceBuffer ServerFragmentFrame::Serialize(HPackCompressor* encoder) const {
BufferPair ServerFragmentFrame::Serialize(HPackCompressor* encoder) const {
GPR_ASSERT(stream_id != 0);
FrameSerializer serializer(FrameType::kFragment, stream_id, message_padding);
FrameSerializer serializer(FrameType::kFragment, stream_id);
if (headers.get() != nullptr) {
encoder->EncodeRawHeaders(*headers.get(), serializer.AddHeaders());
}
if (message.has_value()) {
serializer.AddMessage(message.value());
}
if (trailers.get() != nullptr) {
encoder->EncodeRawHeaders(*trailers.get(), serializer.AddTrailers());
}
@ -290,16 +339,15 @@ std::string ServerFragmentFrame::ToString() const {
return absl::StrCat(
"ServerFragmentFrame{stream_id=", stream_id, ", headers=",
headers.get() != nullptr ? headers->DebugString().c_str() : "nullptr",
", message=",
message.get() != nullptr ? message->DebugString().c_str() : "nullptr",
", message_padding=", message_padding, ", trailers=",
", message=", message.has_value() ? message->ToString().c_str() : "none",
", trailers=",
trailers.get() != nullptr ? trailers->DebugString().c_str() : "nullptr",
"}");
}
absl::Status CancelFrame::Deserialize(HPackParser*, const FrameHeader& header,
absl::BitGenRef,
SliceBuffer& slice_buffer) {
absl::BitGenRef, Arena*,
BufferPair buffers) {
if (header.type != FrameType::kCancel) {
return absl::InvalidArgumentError("Expected cancel frame");
}
@ -309,14 +357,17 @@ absl::Status CancelFrame::Deserialize(HPackParser*, const FrameHeader& header,
if (header.stream_id == 0) {
return absl::InvalidArgumentError("Expected non-zero stream id");
}
FrameDeserializer deserializer(header, slice_buffer);
if (buffers.data.Length() != 0) {
return absl::InvalidArgumentError("Unexpected data");
}
FrameDeserializer deserializer(header, buffers);
stream_id = header.stream_id;
return deserializer.Finish();
}
SliceBuffer CancelFrame::Serialize(HPackCompressor*) const {
BufferPair CancelFrame::Serialize(HPackCompressor*) const {
GPR_ASSERT(stream_id != 0);
FrameSerializer serializer(FrameType::kCancel, stream_id, 0);
FrameSerializer serializer(FrameType::kCancel, stream_id);
return serializer.Finish();
}

@ -28,6 +28,7 @@
#include "src/core/ext/transport/chaotic_good/frame_header.h"
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
#include "src/core/lib/gprpp/match.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/transport/metadata_batch.h"
@ -36,20 +37,21 @@
namespace grpc_core {
namespace chaotic_good {
struct BufferPair {
SliceBuffer control;
SliceBuffer data;
};
class FrameInterface {
public:
virtual absl::Status Deserialize(HPackParser* parser,
const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) = 0;
virtual SliceBuffer Serialize(HPackCompressor* encoder) const = 0;
absl::BitGenRef bitsrc, Arena* arena,
BufferPair buffers) = 0;
virtual BufferPair Serialize(HPackCompressor* encoder) const = 0;
virtual std::string ToString() const = 0;
protected:
static bool EqVal(const Message& a, const Message& b) {
return a.payload()->JoinIntoString() == b.payload()->JoinIntoString() &&
a.flags() == b.flags();
}
static bool EqVal(const grpc_metadata_batch& a,
const grpc_metadata_batch& b) {
return a.DebugString() == b.DebugString();
@ -65,57 +67,75 @@ class FrameInterface {
struct SettingsFrame final : public FrameInterface {
absl::Status Deserialize(HPackParser* parser, const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) override;
SliceBuffer Serialize(HPackCompressor* encoder) const override;
absl::BitGenRef bitsrc, Arena* arena,
BufferPair buffers) override;
BufferPair Serialize(HPackCompressor* encoder) const override;
std::string ToString() const override;
bool operator==(const SettingsFrame&) const { return true; }
};
struct FragmentMessage {
FragmentMessage(MessageHandle message, uint32_t padding, uint32_t length)
: message(std::move(message)), padding(padding), length(length) {}
MessageHandle message;
uint32_t padding;
uint32_t length;
std::string ToString() const;
static bool EqVal(const Message& a, const Message& b) {
return a.payload()->JoinIntoString() == b.payload()->JoinIntoString() &&
a.flags() == b.flags();
}
bool operator==(const FragmentMessage& other) const {
return EqVal(*message, *other.message) && length == other.length;
}
};
struct ClientFragmentFrame final : public FrameInterface {
absl::Status Deserialize(HPackParser* parser, const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) override;
SliceBuffer Serialize(HPackCompressor* encoder) const override;
absl::BitGenRef bitsrc, Arena* arena,
BufferPair buffers) override;
BufferPair Serialize(HPackCompressor* encoder) const override;
std::string ToString() const override;
uint32_t stream_id;
ClientMetadataHandle headers;
MessageHandle message;
uint32_t message_padding;
absl::optional<FragmentMessage> message;
bool end_of_stream = false;
bool operator==(const ClientFragmentFrame& other) const {
return stream_id == other.stream_id && EqHdl(headers, other.headers) &&
end_of_stream == other.end_of_stream;
message == other.message && end_of_stream == other.end_of_stream;
}
};
struct ServerFragmentFrame final : public FrameInterface {
absl::Status Deserialize(HPackParser* parser, const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) override;
SliceBuffer Serialize(HPackCompressor* encoder) const override;
absl::BitGenRef bitsrc, Arena* arena,
BufferPair buffers) override;
BufferPair Serialize(HPackCompressor* encoder) const override;
std::string ToString() const override;
uint32_t stream_id;
ServerMetadataHandle headers;
MessageHandle message;
uint32_t message_padding;
absl::optional<FragmentMessage> message;
ServerMetadataHandle trailers;
bool operator==(const ServerFragmentFrame& other) const {
return stream_id == other.stream_id && EqHdl(headers, other.headers) &&
EqHdl(trailers, other.trailers);
message == other.message && EqHdl(trailers, other.trailers);
}
};
struct CancelFrame final : public FrameInterface {
absl::Status Deserialize(HPackParser* parser, const FrameHeader& header,
absl::BitGenRef bitsrc,
SliceBuffer& slice_buffer) override;
SliceBuffer Serialize(HPackCompressor* encoder) const override;
absl::BitGenRef bitsrc, Arena* arena,
BufferPair buffers) override;
BufferPair Serialize(HPackCompressor* encoder) const override;
std::string ToString() const override;
uint32_t stream_id;
@ -128,6 +148,19 @@ struct CancelFrame final : public FrameInterface {
using ClientFrame = absl::variant<ClientFragmentFrame, CancelFrame>;
using ServerFrame = absl::variant<ServerFragmentFrame>;
inline FrameInterface& GetFrameInterface(ClientFrame& frame) {
return MatchMutable(
&frame,
[](ClientFragmentFrame* frame) -> FrameInterface& { return *frame; },
[](CancelFrame* frame) -> FrameInterface& { return *frame; });
}
inline FrameInterface& GetFrameInterface(ServerFrame& frame) {
return MatchMutable(
&frame,
[](ServerFragmentFrame* frame) -> FrameInterface& { return *frame; });
}
} // namespace chaotic_good
} // namespace grpc_core

@ -19,6 +19,7 @@
#include <cstdint>
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include <grpc/support/log.h>
@ -46,7 +47,6 @@ void FrameHeader::Serialize(uint8_t* data) const {
WriteLittleEndianUint32(
static_cast<uint32_t>(type) | (flags.ToInt<uint32_t>() << 8), data);
if (flags.is_set(0)) GPR_ASSERT(header_length > 0);
if (flags.is_set(1)) GPR_ASSERT(trailer_length > 0);
WriteLittleEndianUint32(stream_id, data + 4);
WriteLittleEndianUint32(header_length, data + 8);
WriteLittleEndianUint32(message_length, data + 12);
@ -60,8 +60,8 @@ absl::StatusOr<FrameHeader> FrameHeader::Parse(const uint8_t* data) {
const uint32_t type_and_flags = ReadLittleEndianUint32(data);
header.type = static_cast<FrameType>(type_and_flags & 0xff);
const uint32_t flags = type_and_flags >> 8;
if (flags > 3) return absl::InvalidArgumentError("Invalid flags");
header.flags = BitSet<2>::FromInt(flags);
if (flags > 7) return absl::InvalidArgumentError("Invalid flags");
header.flags = BitSet<3>::FromInt(flags);
header.stream_id = ReadLittleEndianUint32(data + 4);
header.header_length = ReadLittleEndianUint32(data + 8);
if (header.flags.is_set(0) && header.header_length <= 0) {
@ -70,11 +70,11 @@ absl::StatusOr<FrameHeader> FrameHeader::Parse(const uint8_t* data) {
}
header.message_length = ReadLittleEndianUint32(data + 12);
header.message_padding = ReadLittleEndianUint32(data + 16);
header.trailer_length = ReadLittleEndianUint32(data + 20);
if (header.flags.is_set(1) && header.trailer_length <= 0) {
if (header.flags.is_set(1) && header.message_length <= 0) {
return absl::InvalidArgumentError(
absl::StrCat("Invalid trailer length", header.trailer_length));
absl::StrCat("Invalid message length: ", header.message_length));
}
header.trailer_length = ReadLittleEndianUint32(data + 20);
return header;
}

@ -36,7 +36,7 @@ enum class FrameType : uint8_t {
struct FrameHeader {
FrameType type = FrameType::kCancel;
BitSet<2> flags;
BitSet<3> flags;
uint32_t stream_id = 0;
uint32_t header_length = 0;
uint32_t message_length = 0;

@ -0,0 +1,332 @@
// Copyright 2022 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 <grpc/support/port_platform.h>
#include "src/core/ext/transport/chaotic_good/server_transport.h"
#include <memory>
#include <string>
#include <tuple>
#include "absl/random/bit_gen_ref.h"
#include "absl/random/random.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/slice.h>
#include <grpc/support/log.h>
#include "src/core/ext/transport/chaotic_good/frame.h"
#include "src/core/ext/transport/chaotic_good/frame_header.h"
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/event_engine_wakeup_scheduler.h"
#include "src/core/lib/promise/for_each.h"
#include "src/core/lib/promise/loop.h"
#include "src/core/lib/promise/switch.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/resource_quota/resource_quota.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/transport/promise_endpoint.h"
namespace grpc_core {
namespace chaotic_good {
auto ChaoticGoodServerTransport::TransportWriteLoop() {
return Loop([this] {
return TrySeq(
// Get next outgoing frame.
outgoing_frames_.Next(),
// Serialize and write it out.
[this](ServerFrame client_frame) {
return transport_.WriteFrame(GetFrameInterface(client_frame));
},
[]() -> LoopCtl<absl::Status> {
// The write failures will be caught in TrySeq and exit loop.
// Therefore, only need to return Continue() in the last lambda
// function.
return Continue();
});
});
}
auto ChaoticGoodServerTransport::PushFragmentIntoCall(
CallInitiator call_initiator, ClientFragmentFrame frame) {
auto& headers = frame.headers;
return TrySeq(
If(
headers != nullptr,
[call_initiator, &headers]() mutable {
return call_initiator.PushClientInitialMetadata(std::move(headers));
},
[]() -> StatusFlag { return Success{}; }),
[call_initiator, message = std::move(frame.message)]() mutable {
return If(
message.has_value(),
[&call_initiator, &message]() mutable {
return call_initiator.PushMessage(std::move(message->message));
},
[]() -> StatusFlag { return Success{}; });
},
[call_initiator,
end_of_stream = frame.end_of_stream]() mutable -> StatusFlag {
if (end_of_stream) call_initiator.FinishSends();
return Success{};
});
}
auto ChaoticGoodServerTransport::MaybePushFragmentIntoCall(
absl::optional<CallInitiator> call_initiator, absl::Status error,
ClientFragmentFrame frame) {
return If(
call_initiator.has_value() && error.ok(),
[this, &call_initiator, &frame]() {
return Map(
call_initiator->SpawnWaitable(
"push-fragment",
[call_initiator, frame = std::move(frame), this]() mutable {
return call_initiator->CancelIfFails(
PushFragmentIntoCall(*call_initiator, std::move(frame)));
}),
[](StatusFlag status) { return StatusCast<absl::Status>(status); });
},
[error = std::move(error)]() { return error; });
}
auto ChaoticGoodServerTransport::CallOutboundLoop(
uint32_t stream_id, CallInitiator call_initiator) {
auto send_fragment = [stream_id,
outgoing_frames = outgoing_frames_.MakeSender()](
ServerFragmentFrame frame) mutable {
frame.stream_id = stream_id;
return Map(outgoing_frames.Send(std::move(frame)),
[](bool success) -> absl::Status {
if (!success) {
// Failed to send outgoing frame.
return absl::UnavailableError("Transport closed.");
}
return absl::OkStatus();
});
};
return Seq(
TrySeq(
// Wait for initial metadata then send it out.
call_initiator.PullServerInitialMetadata(),
[send_fragment](ServerMetadataHandle md) mutable {
ServerFragmentFrame frame;
frame.headers = std::move(md);
return send_fragment(std::move(frame));
},
// Continuously send client frame with client to server messages.
ForEach(OutgoingMessages(call_initiator),
[send_fragment, aligned_bytes = aligned_bytes_](
MessageHandle message) mutable {
ServerFragmentFrame frame;
// Construct frame header (flags, header_length and
// trailer_length will be added in serialization).
const uint32_t message_length =
message->payload()->Length();
const uint32_t padding =
message_length % aligned_bytes == 0
? 0
: aligned_bytes - message_length % aligned_bytes;
GPR_ASSERT((message_length + padding) % aligned_bytes == 0);
frame.message = FragmentMessage(std::move(message), padding,
message_length);
return send_fragment(std::move(frame));
})),
call_initiator.PullServerTrailingMetadata(),
[send_fragment](ServerMetadataHandle md) mutable {
ServerFragmentFrame frame;
frame.trailers = std::move(md);
return send_fragment(std::move(frame));
});
}
auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToNewCall(
FrameHeader frame_header, BufferPair buffers) {
ClientFragmentFrame fragment_frame;
ScopedArenaPtr arena(acceptor_->CreateArena());
absl::Status status = transport_.DeserializeFrame(
frame_header, std::move(buffers), arena.get(), fragment_frame);
absl::optional<CallInitiator> call_initiator;
if (status.ok()) {
auto create_call_result =
acceptor_->CreateCall(*fragment_frame.headers, arena.release());
if (create_call_result.ok()) {
call_initiator.emplace(std::move(*create_call_result));
call_initiator->SpawnGuarded(
"server-write", [this, stream_id = frame_header.stream_id,
call_initiator = *call_initiator]() {
return CallOutboundLoop(stream_id, call_initiator);
});
} else {
status = create_call_result.status();
}
}
return MaybePushFragmentIntoCall(std::move(call_initiator), std::move(status),
std::move(fragment_frame));
}
auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToExistingCall(
FrameHeader frame_header, BufferPair buffers) {
absl::optional<CallInitiator> call_initiator =
LookupStream(frame_header.stream_id);
Arena* arena = nullptr;
if (call_initiator.has_value()) arena = call_initiator->arena();
ClientFragmentFrame fragment_frame;
absl::Status status = transport_.DeserializeFrame(
frame_header, std::move(buffers), arena, fragment_frame);
return MaybePushFragmentIntoCall(std::move(call_initiator), std::move(status),
std::move(fragment_frame));
}
auto ChaoticGoodServerTransport::TransportReadLoop() {
return Loop([this] {
return TrySeq(
transport_.ReadFrameBytes(),
[this](std::tuple<FrameHeader, BufferPair> frame_bytes) {
const auto& frame_header = std::get<0>(frame_bytes);
auto& buffers = std::get<1>(frame_bytes);
return Switch(
frame_header.type,
Case(FrameType::kSettings,
[]() -> absl::Status {
return absl::InternalError("Unexpected settings frame");
}),
Case(FrameType::kFragment,
[this, &frame_header, &buffers]() {
return If(
frame_header.flags.is_set(0),
[this, &frame_header, &buffers]() {
return DeserializeAndPushFragmentToNewCall(
frame_header, std::move(buffers));
},
[this, &frame_header, &buffers]() {
return DeserializeAndPushFragmentToExistingCall(
frame_header, std::move(buffers));
});
}),
Case(FrameType::kCancel,
[this, &frame_header]() {
absl::optional<CallInitiator> call_initiator =
ExtractStream(frame_header.stream_id);
return If(
call_initiator.has_value(),
[&call_initiator]() {
auto c = std::move(*call_initiator);
return c.SpawnWaitable("cancel", [c]() mutable {
c.Cancel();
return absl::OkStatus();
});
},
[]() -> absl::Status {
return absl::InternalError(
"Unexpected cancel frame");
});
}),
Default([frame_header]() {
return absl::InternalError(
absl::StrCat("Unexpected frame type: ",
static_cast<uint8_t>(frame_header.type)));
}));
},
[]() -> LoopCtl<absl::Status> { return Continue{}; });
});
}
auto ChaoticGoodServerTransport::OnTransportActivityDone() {
return [this](absl::Status status) {
if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) {
this->AbortWithError();
}
};
}
ChaoticGoodServerTransport::ChaoticGoodServerTransport(
const ChannelArgs& args, std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint,
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine)
: outgoing_frames_(4),
transport_(std::move(control_endpoint), std::move(data_endpoint)),
allocator_(args.GetObject<ResourceQuota>()
->memory_quota()
->CreateMemoryAllocator("chaotic-good")),
event_engine_(event_engine),
writer_{MakeActivity(TransportWriteLoop(),
EventEngineWakeupScheduler(event_engine),
OnTransportActivityDone())},
reader_{nullptr} {}
void ChaoticGoodServerTransport::SetAcceptor(Acceptor* acceptor) {
GPR_ASSERT(acceptor_ == nullptr);
GPR_ASSERT(acceptor != nullptr);
acceptor_ = acceptor;
reader_ = MakeActivity(TransportReadLoop(),
EventEngineWakeupScheduler(event_engine_),
OnTransportActivityDone());
}
ChaoticGoodServerTransport::~ChaoticGoodServerTransport() {
if (writer_ != nullptr) {
writer_.reset();
}
if (reader_ != nullptr) {
reader_.reset();
}
}
void ChaoticGoodServerTransport::AbortWithError() {
// Mark transport as unavailable when the endpoint write/read failed.
// Close all the available pipes.
outgoing_frames_.MarkClosed();
ReleasableMutexLock lock(&mu_);
StreamMap stream_map = std::move(stream_map_);
stream_map_.clear();
lock.Release();
for (const auto& pair : stream_map) {
auto call_initiator = pair.second;
call_initiator.SpawnInfallible("cancel", [call_initiator]() mutable {
call_initiator.Cancel();
return Empty{};
});
}
}
absl::optional<CallInitiator> ChaoticGoodServerTransport::LookupStream(
uint32_t stream_id) {
MutexLock lock(&mu_);
auto it = stream_map_.find(stream_id);
if (it == stream_map_.end()) return absl::nullopt;
return it->second;
}
absl::optional<CallInitiator> ChaoticGoodServerTransport::ExtractStream(
uint32_t stream_id) {
MutexLock lock(&mu_);
auto it = stream_map_.find(stream_id);
if (it == stream_map_.end()) return absl::nullopt;
auto r = std::move(it->second);
stream_map_.erase(it);
return std::move(r);
}
} // namespace chaotic_good
} // namespace grpc_core

@ -0,0 +1,145 @@
// Copyright 2022 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_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SERVER_TRANSPORT_H
#define GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SERVER_TRANSPORT_H
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include <stdio.h>
#include <cstdint>
#include <initializer_list> // IWYU pragma: keep
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/random/random.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/slice.h>
#include <grpc/support/log.h>
#include "src/core/ext/transport/chaotic_good/chaotic_good_transport.h"
#include "src/core/ext/transport/chaotic_good/frame.h"
#include "src/core/ext/transport/chaotic_good/frame_header.h"
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
#include "src/core/lib/event_engine/default_event_engine.h" // IWYU pragma: keep
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/if.h"
#include "src/core/lib/promise/inter_activity_pipe.h"
#include "src/core/lib/promise/loop.h"
#include "src/core/lib/promise/mpsc.h"
#include "src/core/lib/promise/party.h"
#include "src/core/lib/promise/pipe.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/promise/try_join.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/promise_endpoint.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
namespace chaotic_good {
class ChaoticGoodServerTransport final : public Transport,
public ServerTransport {
public:
ChaoticGoodServerTransport(
const ChannelArgs& args,
std::unique_ptr<PromiseEndpoint> control_endpoint,
std::unique_ptr<PromiseEndpoint> data_endpoint,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine);
~ChaoticGoodServerTransport() override;
FilterStackTransport* filter_stack_transport() override { return nullptr; }
ClientTransport* client_transport() override { return nullptr; }
ServerTransport* server_transport() override { return this; }
absl::string_view GetTransportName() const override { return "chaotic_good"; }
void SetPollset(grpc_stream*, grpc_pollset*) override {}
void SetPollsetSet(grpc_stream*, grpc_pollset_set*) override {}
void PerformOp(grpc_transport_op*) override { Crash("unimplemented"); }
grpc_endpoint* GetEndpoint() override { return nullptr; }
void Orphan() override { delete this; }
void SetAcceptor(Acceptor* acceptor) override;
void AbortWithError();
private:
using StreamMap = absl::flat_hash_map<uint32_t, CallInitiator>;
absl::Status NewStream(uint32_t stream_id, CallInitiator call_initiator);
absl::optional<CallInitiator> LookupStream(uint32_t stream_id);
absl::optional<CallInitiator> ExtractStream(uint32_t stream_id);
auto CallOutboundLoop(uint32_t stream_id, CallInitiator call_initiator);
auto OnTransportActivityDone();
auto TransportReadLoop();
auto TransportWriteLoop();
// Read different parts of the server frame from control/data endpoints
// based on frame header.
// Resolves to a StatusOr<tuple<SliceBuffer, SliceBuffer>>
auto ReadFrameBody(Slice read_buffer);
void SendCancel(uint32_t stream_id, absl::Status why);
auto DeserializeAndPushFragmentToNewCall(FrameHeader frame_header,
BufferPair buffers);
auto DeserializeAndPushFragmentToExistingCall(FrameHeader frame_header,
BufferPair buffers);
auto MaybePushFragmentIntoCall(absl::optional<CallInitiator> call_initiator,
absl::Status error, ClientFragmentFrame frame);
auto PushFragmentIntoCall(CallInitiator call_initiator,
ClientFragmentFrame frame);
Acceptor* acceptor_ = nullptr;
MpscReceiver<ServerFrame> outgoing_frames_;
ChaoticGoodTransport transport_;
// Assigned aligned bytes from setting frame.
size_t aligned_bytes_ = 64;
Mutex mu_;
// Map of stream incoming server frames, key is stream_id.
StreamMap stream_map_ ABSL_GUARDED_BY(mu_);
grpc_event_engine::experimental::MemoryAllocator allocator_;
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_;
ActivityPtr writer_;
ActivityPtr reader_;
};
} // namespace chaotic_good
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SERVER_TRANSPORT_H

@ -617,8 +617,17 @@ void Chttp2ServerListener::ActiveConnection::Start(
RefCountedPtr<HandshakingState> handshaking_state_ref;
listener_ = std::move(listener);
{
MutexLock lock(&mu_);
if (shutdown_) return;
ReleasableMutexLock lock(&mu_);
if (shutdown_) {
lock.Release();
// If the Connection is already shutdown at this point, it implies the
// owning Chttp2ServerListener and all associated ActiveConnections have
// been orphaned. The generated endpoints need to be shutdown here to
// ensure the tcp connections are closed appropriately.
grpc_endpoint_shutdown(endpoint, absl::OkStatus());
grpc_endpoint_destroy(endpoint);
return;
}
// Hold a ref to HandshakingState to allow starting the handshake outside
// the critical region.
handshaking_state_ref = handshaking_state_->Ref();

@ -79,6 +79,7 @@
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/debug/stats_data.h"
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/bitset.h"
#include "src/core/lib/gprpp/crash.h"
@ -342,7 +343,7 @@ void ForEachContextListEntryExecute(void* arg, Timestamps* ts,
}
HttpAnnotation::HttpAnnotation(
Type type, Timestamp time,
Type type, gpr_timespec time,
absl::optional<chttp2::TransportFlowControl::Stats> transport_stats,
absl::optional<chttp2::StreamFlowControl::Stats> stream_stats)
: CallTracerAnnotationInterface::Annotation(
@ -367,7 +368,7 @@ std::string HttpAnnotation::ToString() const {
default:
absl::StrAppend(&s, "Unknown");
}
absl::StrAppend(&s, " time: ", time_.ToString());
absl::StrAppend(&s, " time: ", gpr_format_timespec(time_));
if (transport_stats_.has_value()) {
absl::StrAppend(&s, " transport:[", transport_stats_->ToString(), "]");
}
@ -645,7 +646,7 @@ static void read_channel_args(grpc_chttp2_transport* t,
t->max_concurrent_streams_overload_protection =
channel_args.GetBool(GRPC_ARG_MAX_CONCURRENT_STREAMS_OVERLOAD_PROTECTION)
.value_or(grpc_core::IsOverloadProtectionEnabled());
.value_or(true);
}
static void init_keepalive_pings_if_enabled_locked(
@ -1508,7 +1509,7 @@ static void perform_stream_op_locked(void* stream_op,
if (op->send_initial_metadata) {
if (s->call_tracer) {
s->call_tracer->RecordAnnotation(grpc_core::HttpAnnotation(
grpc_core::HttpAnnotation::Type::kStart, grpc_core::Timestamp::Now(),
grpc_core::HttpAnnotation::Type::kStart, gpr_now(GPR_CLOCK_REALTIME),
s->t->flow_control.stats(), s->flow_control.stats()));
}
if (t->is_client && t->channelz_socket != nullptr) {

@ -113,14 +113,14 @@ class HttpAnnotation : public CallTracerAnnotationInterface::Annotation {
};
HttpAnnotation(
Type type, Timestamp time,
Type type, gpr_timespec time,
absl::optional<chttp2::TransportFlowControl::Stats> transport_stats,
absl::optional<chttp2::StreamFlowControl::Stats> stream_stats);
std::string ToString() const override;
Type http_type() const { return type_; }
Timestamp time() const { return time_; }
gpr_timespec time() const { return time_; }
absl::optional<chttp2::TransportFlowControl::Stats> transport_stats() const {
return transport_stats_;
}
@ -130,7 +130,7 @@ class HttpAnnotation : public CallTracerAnnotationInterface::Annotation {
private:
const Type type_;
const Timestamp time_;
const gpr_timespec time_;
absl::optional<chttp2::TransportFlowControl::Stats> transport_stats_;
absl::optional<chttp2::StreamFlowControl::Stats> stream_stats_;
};

@ -104,16 +104,7 @@ TransportFlowControl::TransportFlowControl(absl::string_view name,
MemoryOwner* memory_owner)
: memory_owner_(memory_owner),
enable_bdp_probe_(enable_bdp_probe),
bdp_estimator_(name),
pid_controller_(PidController::Args()
.set_gain_p(4)
.set_gain_i(8)
.set_gain_d(0)
.set_initial_control_value(TargetLogBdp())
.set_min_control_value(-1)
.set_max_control_value(25)
.set_integral_range(10)),
last_pid_update_(Timestamp::Now()) {}
bdp_estimator_(name) {}
uint32_t TransportFlowControl::DesiredAnnounceSize(bool writing_anyway) const {
const uint32_t target_announced_window =
@ -184,41 +175,6 @@ FlowControlAction TransportFlowControl::UpdateAction(FlowControlAction action) {
return action;
}
// Take in a target and modifies it based on the memory pressure of the system
static double AdjustForMemoryPressure(double memory_pressure, double target) {
// do not increase window under heavy memory pressure.
static const double kLowMemPressure = 0.1;
static const double kZeroTarget = 22;
static const double kHighMemPressure = 0.8;
static const double kMaxMemPressure = 0.9;
if (memory_pressure < kLowMemPressure && target < kZeroTarget) {
target = (target - kZeroTarget) * memory_pressure / kLowMemPressure +
kZeroTarget;
} else if (memory_pressure > kHighMemPressure) {
target *= 1 - std::min(1.0, (memory_pressure - kHighMemPressure) /
(kMaxMemPressure - kHighMemPressure));
}
return target;
}
double TransportFlowControl::TargetLogBdp() {
return AdjustForMemoryPressure(
memory_owner_->is_valid()
? memory_owner_->GetPressureInfo().pressure_control_value
: 0.0,
1 + log2(bdp_estimator_.EstimateBdp()));
}
double TransportFlowControl::SmoothLogBdp(double value) {
Timestamp now = Timestamp::Now();
double bdp_error = value - pid_controller_.last_control_value();
const double dt = (now - last_pid_update_).seconds();
last_pid_update_ = now;
// Limit dt to 100ms
const double kMaxDt = 0.1;
return pid_controller_.Update(bdp_error, dt > kMaxDt ? kMaxDt : dt);
}
double
TransportFlowControl::TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
const {
@ -323,10 +279,8 @@ FlowControlAction TransportFlowControl::PeriodicUpdate() {
// TODO(ncteisen): experiment with setting target to be huge under low
// memory pressure.
uint32_t target = static_cast<uint32_t>(RoundUpToPowerOf2(
Clamp(IsMemoryPressureControllerEnabled()
? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
: pow(2, SmoothLogBdp(TargetLogBdp())),
0.0, static_cast<double>(kMaxInitialWindowSize))));
Clamp(TargetInitialWindowSizeBasedOnMemoryPressureAndBdp(), 0.0,
static_cast<double>(kMaxInitialWindowSize))));
if (target < kMinPositiveInitialWindowSize) target = 0;
if (g_test_only_transport_target_window_estimates_mocker != nullptr) {
// Hook for simulating unusual flow control situations in tests.

@ -40,7 +40,6 @@
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/transport/bdp_estimator.h"
#include "src/core/lib/transport/pid_controller.h"
extern grpc_core::TraceFlag grpc_flowctl_trace;
@ -330,8 +329,6 @@ class TransportFlowControl final {
}
private:
double TargetLogBdp();
double SmoothLogBdp(double value);
double TargetInitialWindowSizeBasedOnMemoryPressureAndBdp() const;
static void UpdateSetting(grpc_chttp2_setting_id id, int64_t* desired_value,
uint32_t new_desired_value,
@ -359,10 +356,6 @@ class TransportFlowControl final {
// bdp estimation
BdpEstimator bdp_estimator_;
// pid controller
PidController pid_controller_;
Timestamp last_pid_update_;
int64_t remote_window_ = kDefaultWindow;
int64_t target_initial_window_size_ = kDefaultWindow;
int64_t target_frame_size_ = kDefaultFrameSize;

@ -674,7 +674,6 @@ static grpc_error_handle init_header_frame_parser(grpc_chttp2_transport* t,
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM);
return init_header_skip_frame_parser(t, priority_type, is_eoh);
} else if (GPR_UNLIKELY(
grpc_core::IsRedMaxConcurrentStreamsEnabled() &&
t->stream_map.size() >=
t->max_concurrent_streams_policy.AdvertiseValue() &&
grpc_core::RandomEarlyDetection(

@ -34,6 +34,7 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/ext/transport/chttp2/transport/context_list_entry.h"
@ -516,7 +517,7 @@ class StreamWriteContext {
if (s_->call_tracer) {
s_->call_tracer->RecordAnnotation(grpc_core::HttpAnnotation(
grpc_core::HttpAnnotation::Type::kHeadWritten,
grpc_core::Timestamp::Now(), s_->t->flow_control.stats(),
gpr_now(GPR_CLOCK_REALTIME), s_->t->flow_control.stats(),
s_->flow_control.stats()));
}
}
@ -648,7 +649,7 @@ class StreamWriteContext {
absl::OkStatus());
if (s_->call_tracer) {
s_->call_tracer->RecordAnnotation(grpc_core::HttpAnnotation(
grpc_core::HttpAnnotation::Type::kEnd, grpc_core::Timestamp::Now(),
grpc_core::HttpAnnotation::Type::kEnd, gpr_now(GPR_CLOCK_REALTIME),
s_->t->flow_control.stats(), s_->flow_control.stats()));
}
}

@ -36,8 +36,8 @@ class InprocServerTransport final : public RefCounted<InprocServerTransport>,
public Transport,
public ServerTransport {
public:
void SetAcceptFunction(AcceptFunction accept_function) override {
accept_ = std::move(accept_function);
void SetAcceptor(Acceptor* acceptor) override {
acceptor_ = acceptor;
ConnectionState expect = ConnectionState::kInitial;
state_.compare_exchange_strong(expect, ConnectionState::kReady,
std::memory_order_acq_rel,
@ -92,7 +92,7 @@ class InprocServerTransport final : public RefCounted<InprocServerTransport>,
case ConnectionState::kReady:
break;
}
return accept_(md);
return acceptor_->CreateCall(md, acceptor_->CreateArena());
}
private:
@ -100,7 +100,7 @@ class InprocServerTransport final : public RefCounted<InprocServerTransport>,
std::atomic<ConnectionState> state_{ConnectionState::kInitial};
std::atomic<bool> disconnecting_{false};
AcceptFunction accept_;
Acceptor* acceptor_;
absl::Status disconnect_error_;
Mutex state_tracker_mu_;
ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(state_tracker_mu_){

@ -44,9 +44,9 @@ namespace grpc_core {
// The interface hierarchy is as follows -
// CallTracerAnnotationInterface
// / \
// | |
// ClientCallTracer CallTracerInterface
// / \
// | |
// CallAttemptTracer ServerCallTracer
// The base class for all tracer implementations.
@ -175,7 +175,8 @@ class ServerCallTracerFactory {
virtual ~ServerCallTracerFactory() {}
virtual ServerCallTracer* CreateNewServerCallTracer(Arena* arena) = 0;
virtual ServerCallTracer* CreateNewServerCallTracer(
Arena* arena, const ChannelArgs& channel_args) = 0;
// Returns true if a server is to be traced, false otherwise.
virtual bool IsServerTraced(const ChannelArgs& /*args*/) { return true; }

@ -331,6 +331,16 @@ auto MapResult(void (Derived::Call::*fn)(ServerMetadata&), Promise x,
});
}
template <typename Promise, typename Derived>
auto MapResult(void (Derived::Call::*fn)(ServerMetadata&, Derived*), Promise x,
FilterCallData<Derived>* call_data) {
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
return Map(std::move(x), [call_data](ServerMetadataHandle md) {
call_data->call.OnServerTrailingMetadata(*md, call_data->channel);
return md;
});
}
template <typename Interceptor, typename Derived, typename SfinaeVoid = void>
struct RunCallImpl;
@ -378,6 +388,33 @@ struct RunCallImpl<ServerMetadataHandle (Derived::Call::*)(ClientMetadata& md,
}
};
template <typename Derived>
struct RunCallImpl<absl::Status (Derived::Call::*)(ClientMetadata& md),
Derived> {
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
FilterCallData<Derived>* call_data)
-> ArenaPromise<ServerMetadataHandle> {
auto status = call_data->call.OnClientInitialMetadata(
*call_args.client_initial_metadata);
if (status.ok()) return next_promise_factory(std::move(call_args));
return Immediate(ServerMetadataFromStatus(status));
}
};
template <typename Derived>
struct RunCallImpl<absl::Status (Derived::Call::*)(ClientMetadata& md,
Derived* channel),
Derived> {
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
FilterCallData<Derived>* call_data)
-> ArenaPromise<ServerMetadataHandle> {
auto status = call_data->call.OnClientInitialMetadata(
*call_args.client_initial_metadata, call_data->channel);
if (status.ok()) return next_promise_factory(std::move(call_args));
return Immediate(ServerMetadataFromStatus(status));
}
};
template <typename Derived>
struct RunCallImpl<
void (Derived::Call::*)(ClientMetadata& md, Derived* channel), Derived> {
@ -593,6 +630,35 @@ inline void InterceptClientInitialMetadata(
});
}
template <typename Derived>
inline void InterceptClientInitialMetadata(
absl::Status (Derived::Call::*fn)(ClientMetadata& md),
typename Derived::Call* call, Derived*, CallSpineInterface* call_spine) {
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
call_spine->client_initial_metadata().receiver.InterceptAndMap(
[call_spine,
call](ClientMetadataHandle md) -> absl::optional<ClientMetadataHandle> {
auto status = call->OnClientInitialMetadata(*md);
if (status.ok()) return std::move(md);
return call_spine->Cancel(ServerMetadataFromStatus(status));
});
}
template <typename Derived>
inline void InterceptClientInitialMetadata(
absl::Status (Derived::Call::*fn)(ClientMetadata& md, Derived* channel),
typename Derived::Call* call, Derived* channel,
CallSpineInterface* call_spine) {
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
call_spine->client_initial_metadata().receiver.InterceptAndMap(
[call_spine, call, channel](
ClientMetadataHandle md) -> absl::optional<ClientMetadataHandle> {
auto status = call->OnClientInitialMetadata(*md, channel);
if (status.ok()) return std::move(md);
return call_spine->Cancel(ServerMetadataFromStatus(status));
});
}
// Returning a promise that resolves to something that can be cast to
// ServerMetadataHandle also counts
template <typename Promise, typename Derived>
@ -872,6 +938,19 @@ inline void InterceptServerTrailingMetadata(
});
}
template <typename Derived>
inline void InterceptServerTrailingMetadata(
void (Derived::Call::*fn)(ServerMetadata&, Derived*),
typename Derived::Call* call, Derived* channel,
CallSpineInterface* call_spine) {
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnServerTrailingMetadata);
call_spine->server_trailing_metadata().sender.InterceptAndMap(
[call, channel](ServerMetadataHandle md) {
call->OnServerTrailingMetadata(*md, channel);
return md;
});
}
template <typename Derived>
inline void InterceptServerTrailingMetadata(
absl::Status (Derived::Call::*fn)(ServerMetadata&),
@ -885,11 +964,11 @@ inline void InterceptServerTrailingMetadata(
});
}
inline void InterceptFinalize(const NoInterceptor*, void*) {}
inline void InterceptFinalize(const NoInterceptor*, void*, void*) {}
template <class Call>
inline void InterceptFinalize(void (Call::*fn)(const grpc_call_final_info*),
Call* call) {
void*, Call* call) {
GPR_DEBUG_ASSERT(fn == &Call::OnFinalize);
GetContext<CallFinalization>()->Add(
[call](const grpc_call_final_info* final_info) {
@ -897,6 +976,17 @@ inline void InterceptFinalize(void (Call::*fn)(const grpc_call_final_info*),
});
}
template <class Derived>
inline void InterceptFinalize(
void (Derived::Call::*fn)(const grpc_call_final_info*, Derived*),
Derived* channel, typename Derived::Call* call) {
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnFinalize);
GetContext<CallFinalization>()->Add(
[call, channel](const grpc_call_final_info* final_info) {
call->OnFinalize(final_info, channel);
});
}
template <typename Derived>
absl::enable_if_t<std::is_empty<FilterCallData<Derived>>::value,
FilterCallData<Derived>*>
@ -994,7 +1084,8 @@ class ImplementChannelFilter : public ChannelFilter {
promise_filter_detail::InterceptServerTrailingMetadata(
&Derived::Call::OnServerTrailingMetadata, call,
static_cast<Derived*>(this), call_spine);
promise_filter_detail::InterceptFinalize(&Derived::Call::OnFinalize, call);
promise_filter_detail::InterceptFinalize(&Derived::Call::OnFinalize,
static_cast<Derived*>(this), call);
}
// Polyfill for the original promise scheme.
@ -1011,7 +1102,7 @@ class ImplementChannelFilter : public ChannelFilter {
promise_filter_detail::InterceptServerToClientMessage(
&Derived::Call::OnServerToClientMessage, call, call_args);
promise_filter_detail::InterceptFinalize(
&Derived::Call::OnFinalize,
&Derived::Call::OnFinalize, static_cast<Derived*>(this),
static_cast<typename Derived::Call*>(&call->call));
return promise_filter_detail::MapResult(
&Derived::Call::OnServerTrailingMetadata,

@ -104,8 +104,8 @@ absl::StatusOr<ServerCallTracerFilter> ServerCallTracerFilter::Create(
} // namespace
void RegisterServerCallTracerFilter(CoreConfiguration::Builder* builder) {
builder->channel_init()->RegisterFilter(GRPC_SERVER_CHANNEL,
&ServerCallTracerFilter::kFilter);
builder->channel_init()->RegisterFilter<ServerCallTracerFilter>(
GRPC_SERVER_CHANNEL);
}
} // namespace grpc_core

@ -33,7 +33,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "src/core/lib/event_engine/posix_engine/native_dns_resolver.h"
#include "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/host_port.h"
@ -93,10 +93,11 @@ LookupHostnameBlocking(absl::string_view name, absl::string_view default_port) {
} // namespace
NativeDNSResolver::NativeDNSResolver(std::shared_ptr<EventEngine> event_engine)
NativePosixDNSResolver::NativePosixDNSResolver(
std::shared_ptr<EventEngine> event_engine)
: event_engine_(std::move(event_engine)) {}
void NativeDNSResolver::LookupHostname(
void NativePosixDNSResolver::LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolved,
absl::string_view name, absl::string_view default_port) {
event_engine_->Run(
@ -105,7 +106,7 @@ void NativeDNSResolver::LookupHostname(
});
}
void NativeDNSResolver::LookupSRV(
void NativePosixDNSResolver::LookupSRV(
EventEngine::DNSResolver::LookupSRVCallback on_resolved,
absl::string_view /* name */) {
// Not supported
@ -115,7 +116,7 @@ void NativeDNSResolver::LookupSRV(
});
}
void NativeDNSResolver::LookupTXT(
void NativePosixDNSResolver::LookupTXT(
EventEngine::DNSResolver::LookupTXTCallback on_resolved,
absl::string_view /* name */) {
// Not supported

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_DNS_RESOLVER_H
#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_DNS_RESOLVER_H
#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_POSIX_DNS_RESOLVER_H
#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_POSIX_DNS_RESOLVER_H
#include <grpc/support/port_platform.h>
@ -34,9 +34,9 @@ namespace experimental {
// An asynchronous DNS resolver which uses the native platform's getaddrinfo
// API. Only supports A/AAAA records.
class NativeDNSResolver : public RefCountedDNSResolverInterface {
class NativePosixDNSResolver : public RefCountedDNSResolverInterface {
public:
explicit NativeDNSResolver(std::shared_ptr<EventEngine> event_engine);
explicit NativePosixDNSResolver(std::shared_ptr<EventEngine> event_engine);
void LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolved,
@ -58,4 +58,4 @@ class NativeDNSResolver : public RefCountedDNSResolverInterface {
} // namespace grpc_event_engine
#endif // GRPC_POSIX_SOCKET_RESOLVE_ADDRESS
#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_DNS_RESOLVER_H
#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_NATIVE_POSIX_DNS_RESOLVER_H

@ -45,7 +45,7 @@
#include "src/core/lib/event_engine/poller.h"
#include "src/core/lib/event_engine/posix.h"
#include "src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h"
#include "src/core/lib/event_engine/posix_engine/native_dns_resolver.h"
#include "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h"
#include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h"
#include "src/core/lib/event_engine/posix_engine/timer.h"
#include "src/core/lib/event_engine/tcp_socket_utils.h"
@ -571,10 +571,10 @@ PosixEventEngine::GetDNSResolver(
std::move(*ares_resolver));
#endif // GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER)
}
GRPC_EVENT_ENGINE_DNS_TRACE("PosixEventEngine:%p creating NativeDNSResolver",
this);
GRPC_EVENT_ENGINE_DNS_TRACE(
"PosixEventEngine:%p creating NativePosixDNSResolver", this);
return std::make_unique<PosixEventEngine::PosixDNSResolver>(
grpc_core::MakeOrphanable<NativeDNSResolver>(shared_from_this()));
grpc_core::MakeOrphanable<NativePosixDNSResolver>(shared_from_this()));
#endif // GRPC_POSIX_SOCKET_RESOLVE_ADDRESS
}

@ -0,0 +1,114 @@
// 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.
#include <grpc/support/port_platform.h>
#ifdef GPR_WINDOWS
#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#include <string>
#include "absl/strings/str_format.h"
#include <grpc/event_engine/event_engine.h>
#include "src/core/lib/event_engine/windows/native_windows_dns_resolver.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/iomgr/error.h"
namespace grpc_event_engine {
namespace experimental {
namespace {
absl::StatusOr<std::vector<EventEngine::ResolvedAddress>>
LookupHostnameBlocking(absl::string_view name, absl::string_view default_port) {
std::vector<EventEngine::ResolvedAddress> addresses;
// parse name, splitting it into host and port parts
std::string host;
std::string port;
grpc_core::SplitHostPort(name, &host, &port);
if (host.empty()) {
return absl::InvalidArgumentError(absl::StrCat("Unparseable name: ", name));
}
if (port.empty()) {
if (default_port.empty()) {
return absl::InvalidArgumentError(
absl::StrFormat("No port in name %s or default_port argument", name));
}
port = std::string(default_port);
}
// Call getaddrinfo
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // ipv4 or ipv6
hints.ai_socktype = SOCK_STREAM; // stream socket
hints.ai_flags = AI_PASSIVE; // for wildcard IP address
struct addrinfo* result = nullptr;
int getaddrinfo_error =
getaddrinfo(host.c_str(), port.c_str(), &hints, &result);
if (getaddrinfo_error != 0) {
return absl::UnknownError(
absl::StrFormat("Address lookup failed for %s os_error: %s", name,
grpc_core::StatusToString(
GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo"))
.c_str()));
}
// Success path: collect and return all addresses
for (auto* resp = result; resp != nullptr; resp = resp->ai_next) {
addresses.emplace_back(resp->ai_addr, resp->ai_addrlen);
}
if (result) freeaddrinfo(result);
return addresses;
}
} // namespace
NativeWindowsDNSResolver::NativeWindowsDNSResolver(
std::shared_ptr<EventEngine> event_engine)
: event_engine_(std::move(event_engine)) {}
void NativeWindowsDNSResolver::LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolved,
absl::string_view name, absl::string_view default_port) {
event_engine_->Run(
[name, default_port, on_resolved = std::move(on_resolved)]() mutable {
on_resolved(LookupHostnameBlocking(name, default_port));
});
}
void NativeWindowsDNSResolver::LookupSRV(
EventEngine::DNSResolver::LookupSRVCallback on_resolved,
absl::string_view /* name */) {
// Not supported
event_engine_->Run([on_resolved = std::move(on_resolved)]() mutable {
on_resolved(absl::UnimplementedError(
"The Native resolver does not support looking up SRV records"));
});
}
void NativeWindowsDNSResolver::LookupTXT(
EventEngine::DNSResolver::LookupTXTCallback on_resolved,
absl::string_view /* name */) {
// Not supported
event_engine_->Run([on_resolved = std::move(on_resolved)]() mutable {
on_resolved(absl::UnimplementedError(
"The Native resolver does not support looking up TXT records"));
});
}
} // namespace experimental
} // namespace grpc_event_engine
#endif // GPR_WINDOWS

@ -0,0 +1,51 @@
// 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.
#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_WINDOWS_NATIVE_WINDOWS_DNS_RESOLVER_H
#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_WINDOWS_NATIVE_WINDOWS_DNS_RESOLVER_H
#include <grpc/support/port_platform.h>
#ifdef GPR_WINDOWS
#include <grpc/event_engine/event_engine.h>
namespace grpc_event_engine {
namespace experimental {
// An asynchronous DNS resolver which uses the native platform's getaddrinfo
// API. Only supports A/AAAA records.
class NativeWindowsDNSResolver : public EventEngine::DNSResolver {
public:
explicit NativeWindowsDNSResolver(std::shared_ptr<EventEngine> event_engine);
void LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolved,
absl::string_view name, absl::string_view default_port) override;
void LookupSRV(EventEngine::DNSResolver::LookupSRVCallback on_resolved,
absl::string_view name) override;
void LookupTXT(EventEngine::DNSResolver::LookupTXTCallback on_resolved,
absl::string_view name) override;
private:
std::shared_ptr<EventEngine> event_engine_;
};
} // namespace experimental
} // namespace grpc_event_engine
#endif
#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_WINDOWS_NATIVE_WINDOWS_DNS_RESOLVER_H

@ -37,6 +37,7 @@
#include "src/core/lib/event_engine/utils.h"
#include "src/core/lib/event_engine/windows/grpc_polled_fd_windows.h"
#include "src/core/lib/event_engine/windows/iocp.h"
#include "src/core/lib/event_engine/windows/native_windows_dns_resolver.h"
#include "src/core/lib/event_engine/windows/windows_endpoint.h"
#include "src/core/lib/event_engine/windows/windows_engine.h"
#include "src/core/lib/event_engine/windows/windows_listener.h"
@ -233,10 +234,9 @@ WindowsEventEngine::GetDNSResolver(
return std::make_unique<WindowsEventEngine::WindowsDNSResolver>(
std::move(*ares_resolver));
#else // GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER)
// TODO(yijiem): Implement a basic A/AAAA-only native resolver in
// WindowsEventEngine.
(void)options;
grpc_core::Crash("unimplemented");
GRPC_EVENT_ENGINE_DNS_TRACE(
"WindowsEventEngine:%p creating NativeWindowsDNSResolver", this);
return std::make_unique<NativeWindowsDNSResolver>(shared_from_this());
#endif // GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER)
}

@ -60,19 +60,12 @@ const char* const description_keepalive_server_fix =
"Allows overriding keepalive_permit_without_calls for servers. Refer "
"https://github.com/grpc/grpc/pull/33917 for more information.";
const char* const additional_constraints_keepalive_server_fix = "{}";
const char* const description_memory_pressure_controller =
"New memory pressure controller";
const char* const additional_constraints_memory_pressure_controller = "{}";
const char* const description_monitoring_experiment =
"Placeholder experiment to prove/disprove our monitoring is working";
const char* const additional_constraints_monitoring_experiment = "{}";
const char* const description_multiping =
"Allow more than one ping to be in flight at a time by default.";
const char* const additional_constraints_multiping = "{}";
const char* const description_overload_protection =
"If chttp2 has more streams than it can handle open, send RST_STREAM "
"immediately on new streams appearing.";
const char* const additional_constraints_overload_protection = "{}";
const char* const description_peer_state_based_framing =
"If set, the max sizes of frames sent to lower layers is controlled based "
"on the peer's memory pressure which is reflected in its max http2 frame "
@ -97,10 +90,6 @@ const char* const description_promise_based_server_call =
"If set, use the new gRPC promise based call code when it's appropriate "
"(ie when all filters in a stack are promise based)";
const char* const additional_constraints_promise_based_server_call = "{}";
const char* const description_red_max_concurrent_streams =
"Perform random early rejection of requests that would exceed a newly "
"reduced MAX_CONCURRENT_STREAMS but are allowed by the current.";
const char* const additional_constraints_red_max_concurrent_streams = "{}";
const char* const description_registered_method_lookup_in_transport =
"Change registered method's lookup point to transport";
const char* const additional_constraints_registered_method_lookup_in_transport =
@ -152,6 +141,9 @@ const char* const description_unconstrained_max_quota_buffer_size =
"Discard the cap on the max free pool size for one memory allocator";
const char* const additional_constraints_unconstrained_max_quota_buffer_size =
"{}";
const char* const description_v3_backend_metric_filter =
"Use the backend metric filter utilizing the v3 filter api";
const char* const additional_constraints_v3_backend_metric_filter = "{}";
const char* const description_v3_channel_idle_filters =
"Use the v3 filter API version of the idle filters.";
const char* const additional_constraints_v3_channel_idle_filters = "{}";
@ -216,15 +208,10 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_keepalive_fix, nullptr, 0, false, false},
{"keepalive_server_fix", description_keepalive_server_fix,
additional_constraints_keepalive_server_fix, nullptr, 0, false, false},
{"memory_pressure_controller", description_memory_pressure_controller,
additional_constraints_memory_pressure_controller, nullptr, 0, false,
true},
{"monitoring_experiment", description_monitoring_experiment,
additional_constraints_monitoring_experiment, nullptr, 0, true, true},
{"multiping", description_multiping, additional_constraints_multiping,
nullptr, 0, false, true},
{"overload_protection", description_overload_protection,
additional_constraints_overload_protection, nullptr, 0, true, true},
{"peer_state_based_framing", description_peer_state_based_framing,
additional_constraints_peer_state_based_framing, nullptr, 0, false, true},
{"pending_queue_cap", description_pending_queue_cap,
@ -235,9 +222,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_promise_based_client_call, nullptr, 0, false, true},
{"promise_based_server_call", description_promise_based_server_call,
additional_constraints_promise_based_server_call, nullptr, 0, false, true},
{"red_max_concurrent_streams", description_red_max_concurrent_streams,
additional_constraints_red_max_concurrent_streams, nullptr, 0, false,
true},
{"registered_method_lookup_in_transport",
description_registered_method_lookup_in_transport,
additional_constraints_registered_method_lookup_in_transport, nullptr, 0,
@ -273,6 +257,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
description_unconstrained_max_quota_buffer_size,
additional_constraints_unconstrained_max_quota_buffer_size, nullptr, 0,
false, true},
{"v3_backend_metric_filter", description_v3_backend_metric_filter,
additional_constraints_v3_backend_metric_filter, nullptr, 0, false, true},
{"v3_channel_idle_filters", description_v3_channel_idle_filters,
additional_constraints_v3_channel_idle_filters, nullptr, 0, false, true},
{"v3_compression_filter", description_v3_compression_filter,
@ -334,19 +320,12 @@ const char* const description_keepalive_server_fix =
"Allows overriding keepalive_permit_without_calls for servers. Refer "
"https://github.com/grpc/grpc/pull/33917 for more information.";
const char* const additional_constraints_keepalive_server_fix = "{}";
const char* const description_memory_pressure_controller =
"New memory pressure controller";
const char* const additional_constraints_memory_pressure_controller = "{}";
const char* const description_monitoring_experiment =
"Placeholder experiment to prove/disprove our monitoring is working";
const char* const additional_constraints_monitoring_experiment = "{}";
const char* const description_multiping =
"Allow more than one ping to be in flight at a time by default.";
const char* const additional_constraints_multiping = "{}";
const char* const description_overload_protection =
"If chttp2 has more streams than it can handle open, send RST_STREAM "
"immediately on new streams appearing.";
const char* const additional_constraints_overload_protection = "{}";
const char* const description_peer_state_based_framing =
"If set, the max sizes of frames sent to lower layers is controlled based "
"on the peer's memory pressure which is reflected in its max http2 frame "
@ -371,10 +350,6 @@ const char* const description_promise_based_server_call =
"If set, use the new gRPC promise based call code when it's appropriate "
"(ie when all filters in a stack are promise based)";
const char* const additional_constraints_promise_based_server_call = "{}";
const char* const description_red_max_concurrent_streams =
"Perform random early rejection of requests that would exceed a newly "
"reduced MAX_CONCURRENT_STREAMS but are allowed by the current.";
const char* const additional_constraints_red_max_concurrent_streams = "{}";
const char* const description_registered_method_lookup_in_transport =
"Change registered method's lookup point to transport";
const char* const additional_constraints_registered_method_lookup_in_transport =
@ -426,6 +401,9 @@ const char* const description_unconstrained_max_quota_buffer_size =
"Discard the cap on the max free pool size for one memory allocator";
const char* const additional_constraints_unconstrained_max_quota_buffer_size =
"{}";
const char* const description_v3_backend_metric_filter =
"Use the backend metric filter utilizing the v3 filter api";
const char* const additional_constraints_v3_backend_metric_filter = "{}";
const char* const description_v3_channel_idle_filters =
"Use the v3 filter API version of the idle filters.";
const char* const additional_constraints_v3_channel_idle_filters = "{}";
@ -490,15 +468,10 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_keepalive_fix, nullptr, 0, false, false},
{"keepalive_server_fix", description_keepalive_server_fix,
additional_constraints_keepalive_server_fix, nullptr, 0, false, false},
{"memory_pressure_controller", description_memory_pressure_controller,
additional_constraints_memory_pressure_controller, nullptr, 0, false,
true},
{"monitoring_experiment", description_monitoring_experiment,
additional_constraints_monitoring_experiment, nullptr, 0, true, true},
{"multiping", description_multiping, additional_constraints_multiping,
nullptr, 0, false, true},
{"overload_protection", description_overload_protection,
additional_constraints_overload_protection, nullptr, 0, true, true},
{"peer_state_based_framing", description_peer_state_based_framing,
additional_constraints_peer_state_based_framing, nullptr, 0, false, true},
{"pending_queue_cap", description_pending_queue_cap,
@ -509,9 +482,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_promise_based_client_call, nullptr, 0, false, true},
{"promise_based_server_call", description_promise_based_server_call,
additional_constraints_promise_based_server_call, nullptr, 0, false, true},
{"red_max_concurrent_streams", description_red_max_concurrent_streams,
additional_constraints_red_max_concurrent_streams, nullptr, 0, false,
true},
{"registered_method_lookup_in_transport",
description_registered_method_lookup_in_transport,
additional_constraints_registered_method_lookup_in_transport, nullptr, 0,
@ -547,6 +517,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
description_unconstrained_max_quota_buffer_size,
additional_constraints_unconstrained_max_quota_buffer_size, nullptr, 0,
false, true},
{"v3_backend_metric_filter", description_v3_backend_metric_filter,
additional_constraints_v3_backend_metric_filter, nullptr, 0, false, true},
{"v3_channel_idle_filters", description_v3_channel_idle_filters,
additional_constraints_v3_channel_idle_filters, nullptr, 0, false, true},
{"v3_compression_filter", description_v3_compression_filter,
@ -608,19 +580,12 @@ const char* const description_keepalive_server_fix =
"Allows overriding keepalive_permit_without_calls for servers. Refer "
"https://github.com/grpc/grpc/pull/33917 for more information.";
const char* const additional_constraints_keepalive_server_fix = "{}";
const char* const description_memory_pressure_controller =
"New memory pressure controller";
const char* const additional_constraints_memory_pressure_controller = "{}";
const char* const description_monitoring_experiment =
"Placeholder experiment to prove/disprove our monitoring is working";
const char* const additional_constraints_monitoring_experiment = "{}";
const char* const description_multiping =
"Allow more than one ping to be in flight at a time by default.";
const char* const additional_constraints_multiping = "{}";
const char* const description_overload_protection =
"If chttp2 has more streams than it can handle open, send RST_STREAM "
"immediately on new streams appearing.";
const char* const additional_constraints_overload_protection = "{}";
const char* const description_peer_state_based_framing =
"If set, the max sizes of frames sent to lower layers is controlled based "
"on the peer's memory pressure which is reflected in its max http2 frame "
@ -645,10 +610,6 @@ const char* const description_promise_based_server_call =
"If set, use the new gRPC promise based call code when it's appropriate "
"(ie when all filters in a stack are promise based)";
const char* const additional_constraints_promise_based_server_call = "{}";
const char* const description_red_max_concurrent_streams =
"Perform random early rejection of requests that would exceed a newly "
"reduced MAX_CONCURRENT_STREAMS but are allowed by the current.";
const char* const additional_constraints_red_max_concurrent_streams = "{}";
const char* const description_registered_method_lookup_in_transport =
"Change registered method's lookup point to transport";
const char* const additional_constraints_registered_method_lookup_in_transport =
@ -700,6 +661,9 @@ const char* const description_unconstrained_max_quota_buffer_size =
"Discard the cap on the max free pool size for one memory allocator";
const char* const additional_constraints_unconstrained_max_quota_buffer_size =
"{}";
const char* const description_v3_backend_metric_filter =
"Use the backend metric filter utilizing the v3 filter api";
const char* const additional_constraints_v3_backend_metric_filter = "{}";
const char* const description_v3_channel_idle_filters =
"Use the v3 filter API version of the idle filters.";
const char* const additional_constraints_v3_channel_idle_filters = "{}";
@ -764,15 +728,10 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_keepalive_fix, nullptr, 0, false, false},
{"keepalive_server_fix", description_keepalive_server_fix,
additional_constraints_keepalive_server_fix, nullptr, 0, false, false},
{"memory_pressure_controller", description_memory_pressure_controller,
additional_constraints_memory_pressure_controller, nullptr, 0, false,
true},
{"monitoring_experiment", description_monitoring_experiment,
additional_constraints_monitoring_experiment, nullptr, 0, true, true},
{"multiping", description_multiping, additional_constraints_multiping,
nullptr, 0, false, true},
{"overload_protection", description_overload_protection,
additional_constraints_overload_protection, nullptr, 0, true, true},
{"peer_state_based_framing", description_peer_state_based_framing,
additional_constraints_peer_state_based_framing, nullptr, 0, false, true},
{"pending_queue_cap", description_pending_queue_cap,
@ -783,9 +742,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_promise_based_client_call, nullptr, 0, false, true},
{"promise_based_server_call", description_promise_based_server_call,
additional_constraints_promise_based_server_call, nullptr, 0, false, true},
{"red_max_concurrent_streams", description_red_max_concurrent_streams,
additional_constraints_red_max_concurrent_streams, nullptr, 0, false,
true},
{"registered_method_lookup_in_transport",
description_registered_method_lookup_in_transport,
additional_constraints_registered_method_lookup_in_transport, nullptr, 0,
@ -821,6 +777,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
description_unconstrained_max_quota_buffer_size,
additional_constraints_unconstrained_max_quota_buffer_size, nullptr, 0,
false, true},
{"v3_backend_metric_filter", description_v3_backend_metric_filter,
additional_constraints_v3_backend_metric_filter, nullptr, 0, false, true},
{"v3_channel_idle_filters", description_v3_channel_idle_filters,
additional_constraints_v3_channel_idle_filters, nullptr, 0, false, true},
{"v3_compression_filter", description_v3_compression_filter,

@ -79,12 +79,9 @@ inline bool IsFreeLargeAllocatorEnabled() { return false; }
inline bool IsHttp2StatsFixEnabled() { return true; }
inline bool IsKeepaliveFixEnabled() { return false; }
inline bool IsKeepaliveServerFixEnabled() { return false; }
inline bool IsMemoryPressureControllerEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
inline bool IsMonitoringExperimentEnabled() { return true; }
inline bool IsMultipingEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_OVERLOAD_PROTECTION
inline bool IsOverloadProtectionEnabled() { return true; }
inline bool IsPeerStateBasedFramingEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_PENDING_QUEUE_CAP
inline bool IsPendingQueueCapEnabled() { return true; }
@ -92,7 +89,6 @@ inline bool IsPendingQueueCapEnabled() { return true; }
inline bool IsPickFirstHappyEyeballsEnabled() { return true; }
inline bool IsPromiseBasedClientCallEnabled() { return false; }
inline bool IsPromiseBasedServerCallEnabled() { return false; }
inline bool IsRedMaxConcurrentStreamsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() { return true; }
inline bool IsPromiseBasedInprocTransportEnabled() { return false; }
@ -107,6 +103,7 @@ inline bool IsTcpFrameSizeTuningEnabled() { return false; }
inline bool IsTcpRcvLowatEnabled() { return false; }
inline bool IsTraceRecordCallopsEnabled() { return false; }
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
inline bool IsV3BackendMetricFilterEnabled() { return false; }
inline bool IsV3ChannelIdleFiltersEnabled() { return false; }
inline bool IsV3CompressionFilterEnabled() { return false; }
inline bool IsV3ServerAuthFilterEnabled() { return false; }
@ -144,12 +141,9 @@ inline bool IsFreeLargeAllocatorEnabled() { return false; }
inline bool IsHttp2StatsFixEnabled() { return true; }
inline bool IsKeepaliveFixEnabled() { return false; }
inline bool IsKeepaliveServerFixEnabled() { return false; }
inline bool IsMemoryPressureControllerEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
inline bool IsMonitoringExperimentEnabled() { return true; }
inline bool IsMultipingEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_OVERLOAD_PROTECTION
inline bool IsOverloadProtectionEnabled() { return true; }
inline bool IsPeerStateBasedFramingEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_PENDING_QUEUE_CAP
inline bool IsPendingQueueCapEnabled() { return true; }
@ -157,7 +151,6 @@ inline bool IsPendingQueueCapEnabled() { return true; }
inline bool IsPickFirstHappyEyeballsEnabled() { return true; }
inline bool IsPromiseBasedClientCallEnabled() { return false; }
inline bool IsPromiseBasedServerCallEnabled() { return false; }
inline bool IsRedMaxConcurrentStreamsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() { return true; }
inline bool IsPromiseBasedInprocTransportEnabled() { return false; }
@ -172,6 +165,7 @@ inline bool IsTcpFrameSizeTuningEnabled() { return false; }
inline bool IsTcpRcvLowatEnabled() { return false; }
inline bool IsTraceRecordCallopsEnabled() { return false; }
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
inline bool IsV3BackendMetricFilterEnabled() { return false; }
inline bool IsV3ChannelIdleFiltersEnabled() { return false; }
inline bool IsV3CompressionFilterEnabled() { return false; }
inline bool IsV3ServerAuthFilterEnabled() { return false; }
@ -209,12 +203,9 @@ inline bool IsFreeLargeAllocatorEnabled() { return false; }
inline bool IsHttp2StatsFixEnabled() { return true; }
inline bool IsKeepaliveFixEnabled() { return false; }
inline bool IsKeepaliveServerFixEnabled() { return false; }
inline bool IsMemoryPressureControllerEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
inline bool IsMonitoringExperimentEnabled() { return true; }
inline bool IsMultipingEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_OVERLOAD_PROTECTION
inline bool IsOverloadProtectionEnabled() { return true; }
inline bool IsPeerStateBasedFramingEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_PENDING_QUEUE_CAP
inline bool IsPendingQueueCapEnabled() { return true; }
@ -222,7 +213,6 @@ inline bool IsPendingQueueCapEnabled() { return true; }
inline bool IsPickFirstHappyEyeballsEnabled() { return true; }
inline bool IsPromiseBasedClientCallEnabled() { return false; }
inline bool IsPromiseBasedServerCallEnabled() { return false; }
inline bool IsRedMaxConcurrentStreamsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() { return true; }
inline bool IsPromiseBasedInprocTransportEnabled() { return false; }
@ -237,6 +227,7 @@ inline bool IsTcpFrameSizeTuningEnabled() { return false; }
inline bool IsTcpRcvLowatEnabled() { return false; }
inline bool IsTraceRecordCallopsEnabled() { return false; }
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
inline bool IsV3BackendMetricFilterEnabled() { return false; }
inline bool IsV3ChannelIdleFiltersEnabled() { return false; }
inline bool IsV3CompressionFilterEnabled() { return false; }
inline bool IsV3ServerAuthFilterEnabled() { return false; }
@ -264,16 +255,13 @@ enum ExperimentIds {
kExperimentIdHttp2StatsFix,
kExperimentIdKeepaliveFix,
kExperimentIdKeepaliveServerFix,
kExperimentIdMemoryPressureController,
kExperimentIdMonitoringExperiment,
kExperimentIdMultiping,
kExperimentIdOverloadProtection,
kExperimentIdPeerStateBasedFraming,
kExperimentIdPendingQueueCap,
kExperimentIdPickFirstHappyEyeballs,
kExperimentIdPromiseBasedClientCall,
kExperimentIdPromiseBasedServerCall,
kExperimentIdRedMaxConcurrentStreams,
kExperimentIdRegisteredMethodLookupInTransport,
kExperimentIdPromiseBasedInprocTransport,
kExperimentIdRegisteredMethodsMap,
@ -286,6 +274,7 @@ enum ExperimentIds {
kExperimentIdTcpRcvLowat,
kExperimentIdTraceRecordCallops,
kExperimentIdUnconstrainedMaxQuotaBufferSize,
kExperimentIdV3BackendMetricFilter,
kExperimentIdV3ChannelIdleFilters,
kExperimentIdV3CompressionFilter,
kExperimentIdV3ServerAuthFilter,
@ -340,10 +329,6 @@ inline bool IsKeepaliveFixEnabled() {
inline bool IsKeepaliveServerFixEnabled() {
return IsExperimentEnabled(kExperimentIdKeepaliveServerFix);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_MEMORY_PRESSURE_CONTROLLER
inline bool IsMemoryPressureControllerEnabled() {
return IsExperimentEnabled(kExperimentIdMemoryPressureController);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
inline bool IsMonitoringExperimentEnabled() {
return IsExperimentEnabled(kExperimentIdMonitoringExperiment);
@ -352,10 +337,6 @@ inline bool IsMonitoringExperimentEnabled() {
inline bool IsMultipingEnabled() {
return IsExperimentEnabled(kExperimentIdMultiping);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_OVERLOAD_PROTECTION
inline bool IsOverloadProtectionEnabled() {
return IsExperimentEnabled(kExperimentIdOverloadProtection);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_PEER_STATE_BASED_FRAMING
inline bool IsPeerStateBasedFramingEnabled() {
return IsExperimentEnabled(kExperimentIdPeerStateBasedFraming);
@ -376,10 +357,6 @@ inline bool IsPromiseBasedClientCallEnabled() {
inline bool IsPromiseBasedServerCallEnabled() {
return IsExperimentEnabled(kExperimentIdPromiseBasedServerCall);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_RED_MAX_CONCURRENT_STREAMS
inline bool IsRedMaxConcurrentStreamsEnabled() {
return IsExperimentEnabled(kExperimentIdRedMaxConcurrentStreams);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() {
return IsExperimentEnabled(kExperimentIdRegisteredMethodLookupInTransport);
@ -428,6 +405,10 @@ inline bool IsTraceRecordCallopsEnabled() {
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() {
return IsExperimentEnabled(kExperimentIdUnconstrainedMaxQuotaBufferSize);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_V3_BACKEND_METRIC_FILTER
inline bool IsV3BackendMetricFilterEnabled() {
return IsExperimentEnabled(kExperimentIdV3BackendMetricFilter);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_V3_CHANNEL_IDLE_FILTERS
inline bool IsV3ChannelIdleFiltersEnabled() {
return IsExperimentEnabled(kExperimentIdV3ChannelIdleFilters);

@ -107,11 +107,6 @@
owner: yashkt@google.com
test_tags: []
allow_in_fuzzing_config: false
- name: memory_pressure_controller
description: New memory pressure controller
expiry: 2024/05/05
owner: ctiller@google.com
test_tags: [resource_quota_test]
- name: monitoring_experiment
description: Placeholder experiment to prove/disprove our monitoring is working
expiry: never-ever
@ -123,13 +118,6 @@
expiry: 2024/01/15
owner: ctiller@google.com
test_tags: [flow_control_test]
- name: overload_protection
description:
If chttp2 has more streams than it can handle open, send RST_STREAM immediately
on new streams appearing.
expiry: 2024/03/03
owner: ctiller@google.com
test_tags: [flow_control_test]
- name: peer_state_based_framing
description:
If set, the max sizes of frames sent to lower layers is controlled based
@ -177,13 +165,6 @@
expiry: 2024/06/14
owner: ctiller@google.com
test_tags: ["core_end2end_test", "cpp_end2end_test", "xds_end2end_test", "logging_test"]
- name: red_max_concurrent_streams
description:
Perform random early rejection of requests that would exceed a newly reduced
MAX_CONCURRENT_STREAMS but are allowed by the current.
expiry: 2024/03/03
owner: ctiller@google.com
test_tags: [flow_control_test]
- name: registered_method_lookup_in_transport
description:
Change registered method's lookup point to transport
@ -253,6 +234,12 @@
expiry: 2024/02/01
owner: ctiller@google.com
test_tags: [resource_quota_test]
- name: v3_backend_metric_filter
description:
Use the backend metric filter utilizing the v3 filter api
expiry: 2024/05/05
owner: ctiller@google.com
test_tags: []
- name: v3_channel_idle_filters
description:
Use the v3 filter API version of the idle filters.

@ -78,12 +78,8 @@
default: false
- name: keepalive_server_fix
default: false
- name: memory_pressure_controller
default: false
- name: monitoring_experiment
default: true
- name: overload_protection
default: true
- name: peer_state_based_framing
default: false
- name: pending_queue_cap
@ -94,8 +90,6 @@
default: false
- name: promise_based_server_call
default: false
- name: red_max_concurrent_streams
default: false
- name: registered_method_lookup_in_transport
default: true
- name: registered_methods_map

@ -81,6 +81,15 @@ class DebugLocation {
};
#endif
template <typename T>
struct ValueWithDebugLocation {
// NOLINTNEXTLINE
ValueWithDebugLocation(T&& value, DebugLocation debug_location = {})
: value(std::forward<T>(value)), debug_location(debug_location) {}
T value;
GPR_NO_UNIQUE_ADDRESS DebugLocation debug_location;
};
#define DEBUG_LOCATION ::grpc_core::DebugLocation(__FILE__, __LINE__)
} // namespace grpc_core

File diff suppressed because it is too large Load Diff

@ -45,6 +45,11 @@ inline absl::Status IntoStatus(absl::Status* status) {
// can participate in TrySeq as result types that affect control flow.
inline bool IsStatusOk(const absl::Status& status) { return status.ok(); }
template <typename T>
inline bool IsStatusOk(const absl::StatusOr<T>& status) {
return status.ok();
}
template <typename To, typename From, typename SfinaeVoid = void>
struct StatusCastImpl;
@ -59,20 +64,52 @@ struct StatusCastImpl<To, const To&> {
};
template <typename T>
struct StatusCastImpl<absl::StatusOr<T>, absl::Status> {
static absl::StatusOr<T> Cast(absl::Status&& t) { return std::move(t); }
struct StatusCastImpl<absl::Status, absl::StatusOr<T>> {
static absl::Status Cast(absl::StatusOr<T>&& t) {
return std::move(t.status());
}
};
template <typename T>
struct StatusCastImpl<absl::StatusOr<T>, const absl::Status&> {
static absl::StatusOr<T> Cast(const absl::Status& t) { return t; }
struct StatusCastImpl<absl::Status, absl::StatusOr<T>&> {
static absl::Status Cast(const absl::StatusOr<T>& t) { return t.status(); }
};
template <typename T>
struct StatusCastImpl<absl::Status, const absl::StatusOr<T>&> {
static absl::Status Cast(const absl::StatusOr<T>& t) { return t.status(); }
};
// StatusCast<> allows casting from one status-bearing type to another,
// regardless of whether the status indicates success or failure.
// This means that we can go from StatusOr to Status safely, but not in the
// opposite direction.
// For cases where the status is guaranteed to be a failure (and hence not
// needing to preserve values) see FailureStatusCast<> below.
template <typename To, typename From>
To StatusCast(From&& from) {
return StatusCastImpl<To, From>::Cast(std::forward<From>(from));
}
template <typename To, typename From, typename SfinaeVoid = void>
struct FailureStatusCastImpl : public StatusCastImpl<To, From> {};
template <typename T>
struct FailureStatusCastImpl<absl::StatusOr<T>, absl::Status> {
static absl::StatusOr<T> Cast(absl::Status&& t) { return std::move(t); }
};
template <typename T>
struct FailureStatusCastImpl<absl::StatusOr<T>, const absl::Status&> {
static absl::StatusOr<T> Cast(const absl::Status& t) { return t; }
};
template <typename To, typename From>
To FailureStatusCast(From&& from) {
GPR_DEBUG_ASSERT(!IsStatusOk(from));
return FailureStatusCastImpl<To, From>::Cast(std::forward<From>(from));
}
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_PROMISE_DETAIL_STATUS_H

File diff suppressed because it is too large Load Diff

@ -33,7 +33,9 @@ class EventEngineWakeupScheduler {
explicit EventEngineWakeupScheduler(
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine)
: event_engine_(std::move(event_engine)) {}
: event_engine_(std::move(event_engine)) {
GPR_ASSERT(event_engine_ != nullptr);
}
template <typename ActivityType>
class BoundScheduler

@ -192,6 +192,10 @@ class If<bool, T, F> {
// If it returns failure, returns failure for the entire combinator.
// If it returns true, evaluates the second promise.
// If it returns false, evaluates the third promise.
// If C is a constant, it's guaranteed that one of the promise factories
// if_true or if_false will be evaluated before returning from this function.
// This makes it safe to capture lambda arguments in the promise factory by
// reference.
template <typename C, typename T, typename F>
promise_detail::If<C, T, F> If(C condition, T if_true, F if_false) {
return promise_detail::If<C, T, F>(std::move(condition), std::move(if_true),

@ -113,9 +113,9 @@ class InterActivityPipe {
if (center_ != nullptr) center_->MarkClosed();
}
bool IsClose() { return center_->IsClosed(); }
bool IsClosed() { return center_->IsClosed(); }
void MarkClose() {
void MarkClosed() {
if (center_ != nullptr) center_->MarkClosed();
}
@ -146,6 +146,12 @@ class InterActivityPipe {
return [center = center_]() { return center->Next(); };
}
bool IsClose() { return center_->IsClosed(); }
void MarkClose() {
if (center_ != nullptr) center_->MarkClosed();
}
private:
RefCountedPtr<Center> center_;
};

@ -103,14 +103,12 @@ class Center : public RefCounted<Center<T>> {
// Mark that the receiver is closed.
void ReceiverClosed() {
MutexLock lock(&mu_);
ReleasableMutexLock lock(&mu_);
if (receiver_closed_) return;
receiver_closed_ = true;
}
// Return whether the receiver is closed.
bool IsClosed() {
MutexLock lock(&mu_);
return receiver_closed_;
auto wakeups = send_wakers_.TakeWakeupSet();
lock.Release();
wakeups.Wakeup();
}
private:
@ -131,8 +129,8 @@ class MpscReceiver;
template <typename T>
class MpscSender {
public:
MpscSender(const MpscSender&) = delete;
MpscSender& operator=(const MpscSender&) = delete;
MpscSender(const MpscSender&) = default;
MpscSender& operator=(const MpscSender&) = default;
MpscSender(MpscSender&&) noexcept = default;
MpscSender& operator=(MpscSender&&) noexcept = default;
@ -140,7 +138,10 @@ class MpscSender {
// Resolves to true if sent, false if the receiver was closed (and the value
// will never be successfully sent).
auto Send(T t) {
return [this, t = std::move(t)]() mutable { return center_->PollSend(t); };
return [center = center_, t = std::move(t)]() mutable -> Poll<bool> {
if (center == nullptr) return false;
return center->PollSend(t);
};
}
bool UnbufferedImmediateSend(T t) {
@ -170,7 +171,6 @@ class MpscReceiver {
~MpscReceiver() {
if (center_ != nullptr) center_->ReceiverClosed();
}
bool IsClosed() { return center_->IsClosed(); }
void MarkClosed() {
if (center_ != nullptr) center_->ReceiverClosed();
}

@ -227,40 +227,42 @@ void Party::RunLocked() {
bool Party::RunParty() {
ScopedActivity activity(this);
promise_detail::Context<Arena> arena_ctx(arena_);
return sync_.RunParty([this](int i) {
// If the participant is null, skip.
// This allows participants to complete whilst wakers still exist
// somewhere.
auto* participant = participants_[i].load(std::memory_order_acquire);
if (participant == nullptr) {
if (grpc_trace_promise_primitives.enabled()) {
gpr_log(GPR_DEBUG, "%s[party] wakeup %d already complete",
DebugTag().c_str(), i);
}
return false;
}
absl::string_view name;
return sync_.RunParty([this](int i) { return RunOneParticipant(i); });
}
bool Party::RunOneParticipant(int i) {
// If the participant is null, skip.
// This allows participants to complete whilst wakers still exist
// somewhere.
auto* participant = participants_[i].load(std::memory_order_acquire);
if (participant == nullptr) {
if (grpc_trace_promise_primitives.enabled()) {
name = participant->name();
gpr_log(GPR_DEBUG, "%s[%s] begin job %d", DebugTag().c_str(),
std::string(name).c_str(), i);
gpr_log(GPR_DEBUG, "%s[party] wakeup %d already complete",
DebugTag().c_str(), i);
}
// Poll the participant.
currently_polling_ = i;
bool done = participant->PollParticipantPromise();
currently_polling_ = kNotPolling;
if (done) {
if (!name.empty()) {
gpr_log(GPR_DEBUG, "%s[%s] end poll and finish job %d",
DebugTag().c_str(), std::string(name).c_str(), i);
}
participants_[i].store(nullptr, std::memory_order_relaxed);
} else if (!name.empty()) {
gpr_log(GPR_DEBUG, "%s[%s] end poll", DebugTag().c_str(),
std::string(name).c_str());
return false;
}
absl::string_view name;
if (grpc_trace_promise_primitives.enabled()) {
name = participant->name();
gpr_log(GPR_DEBUG, "%s[%s] begin job %d", DebugTag().c_str(),
std::string(name).c_str(), i);
}
// Poll the participant.
currently_polling_ = i;
bool done = participant->PollParticipantPromise();
currently_polling_ = kNotPolling;
if (done) {
if (!name.empty()) {
gpr_log(GPR_DEBUG, "%s[%s] end poll and finish job %d",
DebugTag().c_str(), std::string(name).c_str(), i);
}
return done;
});
participants_[i].store(nullptr, std::memory_order_relaxed);
} else if (!name.empty()) {
gpr_log(GPR_DEBUG, "%s[%s] end poll", DebugTag().c_str(),
std::string(name).c_str());
}
return done;
}
void Party::AddParticipants(Participant** participants, size_t count) {

@ -102,7 +102,8 @@ class PartySyncUsingAtomics {
template <typename F>
GRPC_MUST_USE_RESULT bool RunParty(F poll_one_participant) {
uint64_t prev_state;
do {
iteration_.fetch_add(1, std::memory_order_relaxed);
for (;;) {
// Grab the current state, and clear the wakeup bits & add flag.
prev_state = state_.fetch_and(kRefMask | kLocked | kAllocatedMask,
std::memory_order_acquire);
@ -133,9 +134,23 @@ class PartySyncUsingAtomics {
// TODO(ctiller): consider mitigations for the accidental wakeup on owning
// waker creation case -- I currently expect this will be more expensive
// than this quick loop.
} while (!state_.compare_exchange_weak(
prev_state, (prev_state & (kRefMask | kAllocatedMask)),
std::memory_order_acq_rel, std::memory_order_acquire));
if (wake_after_poll_ == 0) {
if (state_.compare_exchange_weak(
prev_state, (prev_state & (kRefMask | kAllocatedMask)),
std::memory_order_acq_rel, std::memory_order_acquire)) {
return false;
}
} else {
if (state_.compare_exchange_weak(
prev_state,
(prev_state & (kRefMask | kAllocatedMask | kLocked)) |
wake_after_poll_,
std::memory_order_acq_rel, std::memory_order_acquire)) {
iteration_.fetch_add(1, std::memory_order_relaxed);
wake_after_poll_ = 0;
}
}
}
return false;
}
@ -186,6 +201,11 @@ class PartySyncUsingAtomics {
// Returns true if the caller should run the party.
GRPC_MUST_USE_RESULT bool ScheduleWakeup(WakeupMask mask);
void WakeAfterPoll(WakeupMask mask) { wake_after_poll_ |= mask; }
uint32_t iteration() const {
return iteration_.load(std::memory_order_relaxed);
}
private:
bool UnreffedLast();
@ -225,6 +245,8 @@ class PartySyncUsingAtomics {
static constexpr uint64_t kOneRef = 1ull << kRefShift;
std::atomic<uint64_t> state_;
std::atomic<uint32_t> iteration_{0};
WakeupMask wake_after_poll_ = 0;
};
class PartySyncUsingMutex {
@ -358,6 +380,20 @@ class Party : public Activity, private Wakeable {
Arena* arena() const { return arena_; }
// Return a promise that resolves to Empty{} when the current party poll is
// complete.
// This is useful for implementing batching and the like: we can hold some
// action until the rest of the party resolves itself.
auto AfterCurrentPoll() {
GPR_DEBUG_ASSERT(Activity::current() == this);
sync_.WakeAfterPoll(CurrentParticipant());
return [this, iteration = sync_.iteration()]() -> Poll<Empty> {
GPR_DEBUG_ASSERT(Activity::current() == this);
if (iteration == sync_.iteration()) return Pending{};
return Empty{};
};
}
class BulkSpawner {
public:
explicit BulkSpawner(Party* party) : party_(party) {}
@ -548,6 +584,7 @@ class Party : public Activity, private Wakeable {
// Add a participant (backs Spawn, after type erasure to ParticipantFactory).
void AddParticipants(Participant** participant, size_t count);
bool RunOneParticipant(int i);
virtual grpc_event_engine::experimental::EventEngine* event_engine()
const = 0;

@ -159,6 +159,51 @@ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7> Seq(
std::move(f5), std::move(f6), std::move(f7), whence);
}
template <typename F0, typename F1, typename F2, typename F3, typename F4,
typename F5, typename F6, typename F7, typename F8>
promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8> Seq(
F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8,
DebugLocation whence = {}) {
return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8>(
std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
std::move(f5), std::move(f6), std::move(f7), std::move(f8), whence);
}
template <typename F0, typename F1, typename F2, typename F3, typename F4,
typename F5, typename F6, typename F7, typename F8, typename F9>
promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9> Seq(
F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9,
DebugLocation whence = {}) {
return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9>(
std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
std::move(f5), std::move(f6), std::move(f7), std::move(f8), std::move(f9),
whence);
}
template <typename F0, typename F1, typename F2, typename F3, typename F4,
typename F5, typename F6, typename F7, typename F8, typename F9,
typename F10>
promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10> Seq(
F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9,
F10 f10, DebugLocation whence = {}) {
return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10>(
std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
std::move(f5), std::move(f6), std::move(f7), std::move(f8), std::move(f9),
std::move(f10), whence);
}
template <typename F0, typename F1, typename F2, typename F3, typename F4,
typename F5, typename F6, typename F7, typename F8, typename F9,
typename F10, typename F11>
promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11> Seq(
F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9,
F10 f10, F11 f11, DebugLocation whence = {}) {
return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11>(
std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
std::move(f5), std::move(f6), std::move(f7), std::move(f8), std::move(f9),
std::move(f10), std::move(f11), whence);
}
// Execute a sequence of operations of unknown length.
// Asynchronously:
// for (element in (begin, end)) {

@ -95,6 +95,30 @@ struct StatusCastImpl<absl::Status, const StatusFlag&> {
}
};
template <typename T>
struct FailureStatusCastImpl<absl::StatusOr<T>, StatusFlag> {
static absl::StatusOr<T> Cast(StatusFlag flag) {
GPR_DEBUG_ASSERT(!flag.ok());
return absl::CancelledError();
}
};
template <typename T>
struct FailureStatusCastImpl<absl::StatusOr<T>, StatusFlag&> {
static absl::StatusOr<T> Cast(StatusFlag flag) {
GPR_DEBUG_ASSERT(!flag.ok());
return absl::CancelledError();
}
};
template <typename T>
struct FailureStatusCastImpl<absl::StatusOr<T>, const StatusFlag&> {
static absl::StatusOr<T> Cast(StatusFlag flag) {
GPR_DEBUG_ASSERT(!flag.ok());
return absl::CancelledError();
}
};
// A value if an operation was successful, or a failure flag if not.
template <typename T>
class ValueOrFailure {

@ -0,0 +1,72 @@
// Copyright 2023 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_SRC_CORE_LIB_PROMISE_SWITCH_H
#define GRPC_SRC_CORE_LIB_PROMISE_SWITCH_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <utility>
#include "src/core/lib/promise/detail/promise_factory.h"
#include "src/core/lib/promise/if.h"
namespace grpc_core {
namespace promise_detail {
template <typename D, typename F>
struct Case {
D discriminator;
F factory;
};
template <typename F>
struct Default {
F factory;
};
} // namespace promise_detail
template <typename D, typename PromiseFactory>
auto Case(D discriminator, PromiseFactory f) {
return promise_detail::Case<D, PromiseFactory>{discriminator, std::move(f)};
}
template <typename PromiseFactory>
auto Default(PromiseFactory f) {
return promise_detail::Default<PromiseFactory>{std::move(f)};
}
// Given a list of cases that result in promise factories, return a single
// promise chosen by the discriminator (the first argument of this function).
// e.g.:
// Switch(1, Case<1>([] { return 43; }), Case<2>([] { return 44; }))
// resolves to 43.
// TODO(ctiller): consider writing a code-generator like we do for seq/join
// so that this lowers into a C switch statement.
template <typename D, typename F>
auto Switch(D, promise_detail::Default<F> def) {
return promise_detail::OncePromiseFactory<void, F>(std::move(def.factory))
.Make();
}
template <typename D, typename F, typename... Others>
auto Switch(D discriminator, promise_detail::Case<D, F> c, Others... others) {
return If(discriminator == c.discriminator, std::move(c.factory),
Switch(discriminator, std::move(others)...));
}
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_PROMISE_SWITCH_H

@ -75,16 +75,16 @@ struct TryJoinTraits {
}
template <typename R>
static R EarlyReturn(absl::Status x) {
return StatusCast<R>(std::move(x));
return FailureStatusCast<R>(std::move(x));
}
template <typename R>
static R EarlyReturn(StatusFlag x) {
return StatusCast<R>(x);
return FailureStatusCast<R>(x);
}
template <typename R, typename T>
static R EarlyReturn(const ValueOrFailure<T>& x) {
GPR_ASSERT(!x.ok());
return StatusCast<R>(Failure{});
return FailureStatusCast<R>(Failure{});
}
template <typename... A>
static auto FinalReturn(A&&... a) {

@ -76,7 +76,7 @@ struct TrySeqTraitsWithSfinae<absl::StatusOr<T>> {
}
template <typename R>
static R ReturnValue(absl::StatusOr<T>&& status) {
return StatusCast<R>(status.status());
return FailureStatusCast<R>(status.status());
}
template <typename F, typename Elem>
static auto CallSeqFactory(F& f, Elem&& elem, absl::StatusOr<T> value)
@ -86,11 +86,26 @@ struct TrySeqTraitsWithSfinae<absl::StatusOr<T>> {
template <typename Result, typename RunNext>
static Poll<Result> CheckResultAndRunNext(absl::StatusOr<T> prior,
RunNext run_next) {
if (!prior.ok()) return StatusCast<Result>(prior.status());
if (!prior.ok()) return FailureStatusCast<Result>(prior.status());
return run_next(std::move(prior));
}
};
template <typename T>
struct AllowGenericTrySeqTraits {
static constexpr bool value = true;
};
template <>
struct AllowGenericTrySeqTraits<absl::Status> {
static constexpr bool value = false;
};
template <typename T>
struct AllowGenericTrySeqTraits<absl::StatusOr<T>> {
static constexpr bool value = false;
};
template <typename T, typename AnyType = void>
struct TakeValueExists {
static constexpr bool value = false;
@ -107,7 +122,7 @@ template <typename T>
struct TrySeqTraitsWithSfinae<
T, absl::enable_if_t<
std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value &&
!TakeValueExists<T>::value,
!TakeValueExists<T>::value && AllowGenericTrySeqTraits<T>::value,
void>> {
using UnwrappedType = void;
using WrappedType = T;
@ -121,7 +136,7 @@ struct TrySeqTraitsWithSfinae<
}
template <typename R>
static R ReturnValue(T&& status) {
return StatusCast<R>(std::move(status));
return FailureStatusCast<R>(std::move(status));
}
template <typename Result, typename RunNext>
static Poll<Result> CheckResultAndRunNext(T prior, RunNext run_next) {
@ -133,7 +148,7 @@ template <typename T>
struct TrySeqTraitsWithSfinae<
T, absl::enable_if_t<
std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value &&
TakeValueExists<T>::value,
TakeValueExists<T>::value && AllowGenericTrySeqTraits<T>::value,
void>> {
using UnwrappedType = decltype(TakeValue(std::declval<T>()));
using WrappedType = T;
@ -148,7 +163,7 @@ struct TrySeqTraitsWithSfinae<
template <typename R>
static R ReturnValue(T&& status) {
GPR_DEBUG_ASSERT(!IsStatusOk(status));
return StatusCast<R>(status.status());
return FailureStatusCast<R>(status.status());
}
template <typename Result, typename RunNext>
static Poll<Result> CheckResultAndRunNext(T prior, RunNext run_next) {
@ -170,7 +185,7 @@ struct TrySeqTraitsWithSfinae<absl::Status> {
}
template <typename R>
static R ReturnValue(absl::Status&& status) {
return StatusCast<R>(std::move(status));
return FailureStatusCast<R>(std::move(status));
}
template <typename Result, typename RunNext>
static Poll<Result> CheckResultAndRunNext(absl::Status prior,

@ -180,7 +180,7 @@ class Arena {
template <typename T, typename... Args>
T* New(Args&&... args) {
T* t = static_cast<T*>(Alloc(sizeof(T)));
Construct(t, std::forward<Args>(args)...);
new (t) T(std::forward<Args>(args)...);
return t;
}
@ -333,7 +333,7 @@ class Arena {
// value in Arena::PoolSizes, and so this may pessimize total
// arena size.
template <typename T, typename... Args>
PoolPtr<T> MakePooled(Args&&... args) {
static PoolPtr<T> MakePooled(Args&&... args) {
return PoolPtr<T>(new T(std::forward<Args>(args)...), PooledDeleter());
}

@ -658,14 +658,9 @@ BasicMemoryQuota::PressureInfo BasicMemoryQuota::GetPressureInfo() {
if (size < 1) return PressureInfo{1, 1, 1};
PressureInfo pressure_info;
pressure_info.instantaneous_pressure = std::max(0.0, (size - free) / size);
if (IsMemoryPressureControllerEnabled()) {
pressure_info.pressure_control_value =
pressure_tracker_.AddSampleAndGetControlValue(
pressure_info.instantaneous_pressure);
} else {
pressure_info.pressure_control_value =
std::min(pressure_info.instantaneous_pressure, 1.0);
}
pressure_info.pressure_control_value =
pressure_tracker_.AddSampleAndGetControlValue(
pressure_info.instantaneous_pressure);
pressure_info.max_recommended_allocation_size = quota_size / 16;
return pressure_info;
}

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

Loading…
Cancel
Save