Merge branch 'master' of github.com:grpc/grpc into tls_version

pull/34861/head
Luwei Ge 12 months ago
commit f9a1215ac1
  1. 2
      .bazelversion
  2. 4
      .gitattributes
  3. 6
      .github/labeler.yml
  4. 3
      .github/workflows/pr-auto-fix.yaml
  5. 15
      .github/workflows/pr-auto-tag.yaml
  6. 2
      .gitignore
  7. 26
      BUILD
  8. 1569
      CMakeLists.txt
  9. 1469
      Makefile
  10. 3
      OWNERS
  11. 1520
      Package.swift
  12. 6
      WORKSPACE
  13. 2
      _metadata.py
  14. 74
      bazel/experiments.bzl
  15. 2
      bazel/googleapis.BUILD
  16. 13
      bazel/grpc_build_system.bzl
  17. 61
      bazel/grpc_deps.bzl
  18. 3
      bazel/grpc_extra_deps.bzl
  19. 3
      bazel/supported_versions.txt
  20. 7
      bazel/test_experiments.bzl
  21. 14
      bazel/update_mirror.sh
  22. 3272
      build_autogenerated.yaml
  23. 2
      build_config.rb
  24. 12
      build_handwritten.yaml
  25. 2
      cmake/upb.cmake
  26. 848
      config.m4
  27. 1118
      config.w32
  28. 11
      doc/bazel_support.md
  29. 3
      doc/g_stands_for.md
  30. 12
      doc/service_config.md
  31. 42
      examples/cpp/debugging/BUILD
  32. 132
      examples/cpp/debugging/README.md
  33. 92
      examples/cpp/debugging/crashing_greeter_client.cc
  34. 86
      examples/cpp/debugging/greeter_callback_server_admin.cc
  35. 22
      fuzztest/core/transport/chttp2/BUILD
  36. 79
      fuzztest/core/transport/chttp2/hpack_encoder_timeout_test.cc
  37. 1750
      gRPC-C++.podspec
  38. 2390
      gRPC-Core.podspec
  39. 2
      gRPC-ProtoRPC.podspec
  40. 2
      gRPC-RxLibrary.podspec
  41. 4
      gRPC.podspec
  42. 1514
      grpc.gemspec
  43. 807
      grpc.gyp
  44. 71
      include/grpc/event_engine/event_engine.h
  45. 6
      include/grpc/event_engine/internal/memory_allocator_impl.h
  46. 4
      include/grpc/event_engine/memory_allocator.h
  47. 13
      include/grpc/grpc_crl_provider.h
  48. 5
      include/grpc/grpc_security.h
  49. 7
      include/grpc/impl/channel_arg_names.h
  50. 2
      include/grpc/impl/slice_type.h
  51. 5
      include/grpcpp/security/tls_credentials_options.h
  52. 4
      include/grpcpp/version_info.h
  53. 1518
      package.xml
  54. 1
      requirements.bazel.txt
  55. 2
      setup.cfg
  56. 6
      setup.py
  57. 247
      src/core/BUILD
  58. 18
      src/core/ext/filters/client_channel/client_channel.cc
  59. 59
      src/core/ext/filters/client_channel/lb_policy/address_filtering.cc
  60. 5
      src/core/ext/filters/client_channel/lb_policy/address_filtering.h
  61. 2
      src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc
  62. 13
      src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc
  63. 8
      src/core/ext/filters/client_channel/lb_policy/endpoint_list.h
  64. 210
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  65. 5
      src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc
  66. 122
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  67. 3
      src/core/ext/filters/client_channel/lb_policy/priority/priority.cc
  68. 18
      src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc
  69. 27
      src/core/ext/filters/client_channel/lb_policy/rls/rls.cc
  70. 29
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  71. 20
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  72. 44
      src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc
  73. 15
      src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
  74. 39
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  75. 4
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
  76. 5
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
  77. 71
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
  78. 83
      src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc
  79. 9
      src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc
  80. 261
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  81. 71
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
  82. 1
      src/core/ext/filters/client_channel/retry_filter.cc
  83. 12
      src/core/ext/filters/deadline/deadline_filter.cc
  84. 55
      src/core/ext/filters/http/client/http_client_filter.cc
  85. 15
      src/core/ext/filters/http/client/http_client_filter.h
  86. 74
      src/core/ext/filters/http/server/http_server_filter.cc
  87. 15
      src/core/ext/filters/http/server/http_server_filter.h
  88. 124
      src/core/ext/filters/message_size/message_size_filter.cc
  89. 58
      src/core/ext/filters/message_size/message_size_filter.h
  90. 112
      src/core/ext/transport/chaotic_good/client_transport.cc
  91. 138
      src/core/ext/transport/chaotic_good/client_transport.h
  92. 6
      src/core/ext/transport/chaotic_good/frame.cc
  93. 1
      src/core/ext/transport/chaotic_good/frame.h
  94. 112
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  95. 9
      src/core/ext/transport/chttp2/transport/chttp2_transport.h
  96. 14
      src/core/ext/transport/chttp2/transport/flow_control.cc
  97. 2
      src/core/ext/transport/chttp2/transport/frame_rst_stream.cc
  98. 26
      src/core/ext/transport/chttp2/transport/hpack_encoder.cc
  99. 10
      src/core/ext/transport/chttp2/transport/hpack_encoder.h
  100. 7
      src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1 +1 @@
6.3.2
6.4.0

4
.gitattributes vendored

@ -1,5 +1,5 @@
src/core/ext/upb-generated/** linguist-generated=true
src/core/ext/upbdefs-generated/** linguist-generated=true
src/core/ext/upb-gen/** linguist-generated=true
src/core/ext/upbdefs-gen/** linguist-generated=true
Makefile linguist-generated=true
BUILD.gn linguist-generated=true
CMakeLists.txt linguist-generated=true

@ -52,9 +52,3 @@ lang/ruby:
"lang/C#":
- src/compiler/csharp*
- src/csharp/**
"disposition/Needs Internal Changes":
- src/core/lib/event_engine/windows/**
- src/core/lib/gpr/windows/**
- src/core/lib/gprpp/windows/**
- test/core/event_engine/windows/**

@ -48,8 +48,9 @@ jobs:
with:
script: |
// If you'd like not to run this code on your commits, add your github user id here:
NO_AUTOFIX_USERS = []
NO_AUTOFIX_USERS = ["copybara-service[bot]"]
const { owner, repo } = context.repo
console.log("Actor: " + context.actor);
if (NO_AUTOFIX_USERS.includes(context.actor)) {
console.log('Cancelling');
const run_id = "${{ github.run_id }}";

@ -1,4 +1,4 @@
name: PR Title Check & Tag
name: PR Auto Tag
on:
pull_request_target:
types: [opened, reopened, synchronize, edited]
@ -17,16 +17,3 @@ jobs:
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: ""
title-check:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: thehanimo/pr-title-checker@v1.3.5
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
pass_on_octokit_error: false
configuration_path: ".github/pr_title_checker_config.json"

2
.gitignore vendored

@ -17,7 +17,7 @@ cython_debug/
dist/
htmlcov/
py3*/
python_build/
pyb/
python_pylint_venv/
src/python/grpcio_*/=*
src/python/grpcio_*/build/

26
BUILD

@ -30,8 +30,8 @@ licenses(["reciprocal"])
package(
default_visibility = ["//visibility:public"],
features = [
"layering_check",
"-parse_headers",
"layering_check",
],
)
@ -211,11 +211,11 @@ config_setting(
python_config_settings()
# This should be updated along with build_handwritten.yaml
g_stands_for = "gjallarhorn" # @unused
g_stands_for = "grand" # @unused
core_version = "36.0.0" # @unused
core_version = "37.0.0" # @unused
version = "1.60.0-dev" # @unused
version = "1.61.0-dev" # @unused
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@ -1009,6 +1009,7 @@ grpc_cc_library(
"absl/strings",
"absl/types:optional",
"absl/types:span",
"upb_base_lib",
"upb_collections_lib",
"upb_lib",
],
@ -1213,6 +1214,7 @@ grpc_cc_library(
"include/grpcpp/security/alts_util.h",
],
external_deps = [
"upb_base_lib",
"upb_collections_lib",
"upb_lib",
],
@ -1602,6 +1604,7 @@ grpc_cc_library(
"//src/core:slice_refcount",
"//src/core:socket_mutator",
"//src/core:stats_data",
"//src/core:status_flag",
"//src/core:status_helper",
"//src/core:strerror",
"//src/core:thread_quota",
@ -1930,6 +1933,7 @@ grpc_cc_library(
"absl/synchronization",
"absl/memory",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
"protobuf_headers",
"absl/container:inlined_vector",
@ -2004,6 +2008,7 @@ grpc_cc_library(
"absl/synchronization",
"absl/types:optional",
"absl/memory",
"upb_base_lib",
"upb_lib",
"absl/strings:str_format",
"protobuf_headers",
@ -2173,6 +2178,7 @@ grpc_cc_library(
"absl/strings",
"absl/time",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
],
language = "c++",
@ -2936,6 +2942,7 @@ grpc_cc_library(
"//src/core:lib/resolver/endpoint_addresses.h",
],
external_deps = [
"absl/functional:function_ref",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -3063,6 +3070,7 @@ grpc_cc_library(
"absl/strings:cord",
"absl/types:optional",
"absl/types:variant",
"upb_base_lib",
"upb_collections_lib",
"upb_lib",
],
@ -3673,7 +3681,9 @@ grpc_cc_library(
"absl/strings",
"absl/strings:str_format",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
"upb_mem_lib",
"upb_textformat_lib",
"upb_json_lib",
"upb_reflection",
@ -3748,9 +3758,9 @@ grpc_cc_library(
hdrs = ["//src/core:ext/filters/client_channel/resolver/fake/fake_resolver.h"],
external_deps = [
"absl/base:core_headers",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/time",
"absl/types:optional",
],
language = "c++",
visibility = [
@ -3760,7 +3770,6 @@ grpc_cc_library(
deps = [
"config",
"debug_location",
"endpoint_addresses",
"gpr",
"grpc_public_hdrs",
"grpc_resolver",
@ -3769,7 +3778,6 @@ grpc_cc_library(
"uri_parser",
"work_serializer",
"//src/core:channel_args",
"//src/core:grpc_service_config",
"//src/core:notification",
"//src/core:ref_counted",
"//src/core:useful",
@ -3863,8 +3871,10 @@ grpc_cc_library(
deps = [
"gpr",
"grpc_base",
"ref_counted_ptr",
"//src/core:error",
"//src/core:hpack_constants",
"//src/core:ref_counted",
"//src/core:slice",
"//src/core:status_helper",
],

1569
CMakeLists.txt generated

File diff suppressed because it is too large Load Diff

1469
Makefile generated

File diff suppressed because it is too large Load Diff

@ -1,3 +0,0 @@
# Top level ownership
@markdroth **/OWNERS
@a11r **/OWNERS

1520
Package.swift generated

File diff suppressed because it is too large Load Diff

@ -66,7 +66,7 @@ pip_install(
requirements = "@com_github_grpc_grpc//:requirements.bazel.txt",
)
load("@upb//bazel:system_python.bzl", "system_python")
load("@com_google_protobuf//bazel:system_python.bzl", "system_python")
system_python(
name = "system_python",
@ -77,9 +77,9 @@ load("@system_python//:pip.bzl", "pip_parse")
pip_parse(
name = "pip_deps",
requirements = "@upb//python:requirements.txt",
requirements = "@com_google_protobuf//python:requirements.txt",
requirements_overrides = {
"3.11": "@upb//python:requirements_311.txt",
"3.11": "@com_google_protobuf//python:requirements_311.txt",
},
)

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/_metadata.py.template`!!!
__version__ = """1.60.0.dev0"""
__version__ = """1.61.0.dev0"""

@ -16,6 +16,47 @@
"""Dictionary of tags to experiments so we know when to test different experiments."""
EXPERIMENT_ENABLES = {
"call_status_override_on_cancellation": "call_status_override_on_cancellation",
"canary_client_privacy": "canary_client_privacy",
"client_idleness": "client_idleness",
"client_privacy": "client_privacy",
"event_engine_client": "event_engine_client",
"event_engine_dns": "event_engine_dns",
"event_engine_listener": "event_engine_listener",
"free_large_allocator": "free_large_allocator",
"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_inproc_transport": "promise_based_inproc_transport",
"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",
"registered_methods_map": "registered_methods_map",
"rfc_max_concurrent_streams": "rfc_max_concurrent_streams",
"round_robin_delegate_to_pick_first": "round_robin_delegate_to_pick_first",
"rstpit": "rstpit",
"schedule_cancellation_over_write": "schedule_cancellation_over_write",
"server_privacy": "server_privacy",
"tcp_frame_size_tuning": "tcp_frame_size_tuning",
"tcp_rcv_lowat": "tcp_rcv_lowat",
"trace_record_callops": "trace_record_callops",
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
"work_serializer_dispatch": "work_serializer_dispatch",
"write_size_policy": "write_size_policy",
"write_size_cap": "write_size_cap,write_size_policy",
"wrr_delegate_to_pick_first": "wrr_delegate_to_pick_first",
}
EXPERIMENTS = {
"windows": {
"dbg": {
@ -65,17 +106,9 @@ EXPERIMENTS = {
],
},
"on": {
"bad_client_test": [
"block_excessive_requests_before_settings_ack",
"tarpit",
],
"core_end2end_test": [
"event_engine_listener",
],
"cpp_end2end_test": [
"chttp2_batch_requests",
"chttp2_offload_on_rst_stream",
],
"cpp_lb_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
@ -85,9 +118,6 @@ EXPERIMENTS = {
"event_engine_listener",
],
"flow_control_test": [
"chttp2_batch_requests",
"chttp2_offload_on_rst_stream",
"lazier_stream_updates",
"overload_protection",
"write_size_cap",
"write_size_policy",
@ -155,23 +185,12 @@ EXPERIMENTS = {
],
},
"on": {
"bad_client_test": [
"block_excessive_requests_before_settings_ack",
"tarpit",
],
"cpp_end2end_test": [
"chttp2_batch_requests",
"chttp2_offload_on_rst_stream",
],
"cpp_lb_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
"flow_control_test": [
"chttp2_batch_requests",
"chttp2_offload_on_rst_stream",
"lazier_stream_updates",
"overload_protection",
"write_size_cap",
"write_size_policy",
@ -249,17 +268,9 @@ EXPERIMENTS = {
],
},
"on": {
"bad_client_test": [
"block_excessive_requests_before_settings_ack",
"tarpit",
],
"core_end2end_test": [
"event_engine_listener",
],
"cpp_end2end_test": [
"chttp2_batch_requests",
"chttp2_offload_on_rst_stream",
],
"cpp_lb_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
@ -269,9 +280,6 @@ EXPERIMENTS = {
"event_engine_listener",
],
"flow_control_test": [
"chttp2_batch_requests",
"chttp2_offload_on_rst_stream",
"lazier_stream_updates",
"overload_protection",
"write_size_cap",
"write_size_policy",

@ -15,7 +15,7 @@
licenses(["notice"])
package(
default_visibility = ["//visibility:public"]
default_visibility = ["//visibility:public"],
)
# This is needed for the dependency on google_cloud_cpp to work.

@ -29,11 +29,11 @@ Contains macros used throughout the repo.
load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
load("//bazel:copts.bzl", "GRPC_DEFAULT_COPTS")
load("//bazel:experiments.bzl", "EXPERIMENTS")
load("//bazel:test_experiments.bzl", "TEST_EXPERIMENTS")
load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library", "upb_proto_reflection_library")
load("//bazel:experiments.bzl", "EXPERIMENTS", "EXPERIMENT_ENABLES")
load("//bazel:test_experiments.bzl", "TEST_EXPERIMENTS", "TEST_EXPERIMENT_ENABLES")
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
load("@build_bazel_rules_apple//apple/testing/default_runner:ios_test_runner.bzl", "ios_test_runner")
load("@com_google_protobuf//bazel:upb_proto_library.bzl", "upb_proto_library", "upb_proto_reflection_library")
# The set of pollers to test against if a test exercises polling
POLLERS = ["epoll1", "poll"]
@ -204,8 +204,8 @@ def grpc_cc_library(
includes = [
"api/include",
"include",
"src/core/ext/upb-generated", # Once upb code-gen issue is resolved, remove this.
"src/core/ext/upbdefs-generated", # Once upb code-gen issue is resolved, remove this.
"src/core/ext/upb-gen", # Once upb code-gen issue is resolved, remove this.
"src/core/ext/upbdefs-gen", # Once upb code-gen issue is resolved, remove this.
],
alwayslink = alwayslink,
data = data,
@ -418,6 +418,7 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
return tags
experiment_config = list(poller_config)
experiment_enables = {k: v for k, v in EXPERIMENT_ENABLES.items() + TEST_EXPERIMENT_ENABLES.items()}
for mode, config in mode_config.items():
enabled_tags, disabled_tags = config
if enabled_tags != None:
@ -426,7 +427,7 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
config = dict(config)
config["name"] = config["name"] + "@experiment=" + experiment
env = dict(config["env"])
env["GRPC_EXPERIMENTS"] = experiment
env["GRPC_EXPERIMENTS"] = experiment_enables[experiment]
env["GRPC_CI_EXPERIMENTS"] = "1"
config["env"] = env
tags = config["tags"] + ["experiment_variation"]

@ -22,42 +22,57 @@ def grpc_deps():
native.bind(
name = "upb_lib",
actual = "@upb//:upb",
actual = "@com_google_protobuf//upb",
)
native.bind(
name = "upb_amalgamation_lib",
actual = "@com_google_protobuf//upb:amalgamation",
)
native.bind(
name = "upb_base_lib",
actual = "@com_google_protobuf//upb/base",
)
native.bind(
name = "upb_collections_lib",
actual = "@upb//:collections",
actual = "@com_google_protobuf//upb/collections",
)
native.bind(
name = "upb_mem_lib",
actual = "@com_google_protobuf//upb/mem",
)
native.bind(
name = "upb_reflection",
actual = "@upb//:reflection",
actual = "@com_google_protobuf//upb:reflection",
)
native.bind(
name = "upb_lib_descriptor",
actual = "@upb//:descriptor_upb_proto",
actual = "@com_google_protobuf//upb:descriptor_upb_proto",
)
native.bind(
name = "upb_lib_descriptor_reflection",
actual = "@upb//:descriptor_upb_proto_reflection",
actual = "@com_google_protobuf//upb:descriptor_upb_proto_reflection",
)
native.bind(
name = "upb_textformat_lib",
actual = "@upb//:textformat",
actual = "@com_google_protobuf//upb/text",
)
native.bind(
name = "upb_json_lib",
actual = "@upb//:json",
actual = "@com_google_protobuf//upb/json",
)
native.bind(
name = "upb_generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
actual = "@upb//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
actual = "@com_google_protobuf//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
)
native.bind(
@ -243,12 +258,12 @@ def grpc_deps():
if "com_google_protobuf" not in native.existing_rules():
http_archive(
name = "com_google_protobuf",
sha256 = "660ce016f987550bc1ccec4a6ee4199afb871799b696227098e3641476a7d566",
strip_prefix = "protobuf-b2b7a51158418f41cff0520894836c15b1738721",
sha256 = "7ed5fc41fe1614e551025f8e14b79b026a015b3ed337d38920c586f3ea35d818",
strip_prefix = "protobuf-6b5d8db01fe47478e8d400f550e797e6230d464e",
urls = [
# https://github.com/protocolbuffers/protobuf/commits/v24.3
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/b2b7a51158418f41cff0520894836c15b1738721.tar.gz",
"https://github.com/protocolbuffers/protobuf/archive/b2b7a51158418f41cff0520894836c15b1738721.tar.gz",
# https://github.com/protocolbuffers/protobuf/commits/v25.0
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/6b5d8db01fe47478e8d400f550e797e6230d464e.tar.gz",
"https://github.com/protocolbuffers/protobuf/archive/6b5d8db01fe47478e8d400f550e797e6230d464e.tar.gz",
],
patches = [
"@com_github_grpc_grpc//third_party:protobuf.patch",
@ -380,18 +395,6 @@ def grpc_deps():
],
)
if "upb" not in native.existing_rules():
http_archive(
name = "upb",
sha256 = "5147e0ab6a28421d1e49004f4a205d84f06b924585e15eaa884cfe13289165b7",
strip_prefix = "upb-42cd08932e364a4cde35033b73f15c30250d7c2e",
urls = [
# https://github.com/protocolbuffers/upb/commits/24.x
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/42cd08932e364a4cde35033b73f15c30250d7c2e.tar.gz",
"https://github.com/protocolbuffers/upb/archive/42cd08932e364a4cde35033b73f15c30250d7c2e.tar.gz",
],
)
if "envoy_api" not in native.existing_rules():
http_archive(
name = "envoy_api",
@ -509,11 +512,11 @@ def grpc_deps():
if "io_opentelemetry_cpp" not in native.existing_rules():
http_archive(
name = "io_opentelemetry_cpp",
sha256 = "f30cd88bf898a5726d245eba882b8e81012021eb00df34109f4dfb203f005cea",
strip_prefix = "opentelemetry-cpp-1.11.0",
sha256 = "149f076cc7a79bbd3a3c34fb3ab61d3a3e8dcfe2b9596f79153e17123c32f897",
strip_prefix = "opentelemetry-cpp-064fef0d871c57ffac6739d3311659a5770a9db4",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.11.0.tar.gz",
"https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.11.0.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/open-telemetry/opentelemetry-cpp/archive/064fef0d871c57ffac6739d3311659a5770a9db4.tar.gz",
"https://github.com/open-telemetry/opentelemetry-cpp/archive/064fef0d871c57ffac6739d3311659a5770a9db4.tar.gz",
],
)

@ -22,7 +22,6 @@ load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
load("@envoy_api//bazel:repositories.bzl", "api_dependencies")
load("@google_cloud_cpp//bazel:google_cloud_cpp_deps.bzl", "google_cloud_cpp_deps")
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
def grpc_extra_deps(ignore_version_differences = False):
"""Loads the extra dependencies.
@ -49,8 +48,6 @@ def grpc_extra_deps(ignore_version_differences = False):
"""
protobuf_deps()
upb_deps()
api_dependencies()
go_rules_dependencies()

@ -1,2 +1 @@
6.3.2
5.4.1
6.4.0

@ -16,6 +16,13 @@
"""Dictionary of tags to experiments so we know when to test different experiments."""
TEST_EXPERIMENT_ENABLES = {
"test_experiment_1": "test_experiment_1",
"test_experiment_2": "test_experiment_2",
"test_experiment_3": "test_experiment_3",
"test_experiment_4": "test_experiment_4",
}
TEST_EXPERIMENTS = {
"windows": {
"dbg": {

@ -57,17 +57,9 @@ function upload {
# upload "github.com/google/boringssl/archive/1c2769383f027befac5b75b6cedd25daf3bf4dcf.tar.gz"
# bazel binaries used by the tools/bazel wrapper script
upload github.com/bazelbuild/bazel/releases/download/5.4.1/bazel-5.4.1-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/5.4.1/bazel-5.4.1-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/5.4.1/bazel-5.4.1-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/6.3.2/bazel-6.3.2-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.3.2/bazel-6.3.2-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.3.2/bazel-6.3.2-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-windows-x86_64.exe
# Collect the github archives to mirror from grpc_deps.bzl
grep -o '"https://github.com/[^"]*"' bazel/grpc_deps.bzl | sed 's/^"https:\/\///' | sed 's/"$//' | while read -r line ; do

File diff suppressed because it is too large Load Diff

@ -13,5 +13,5 @@
# limitations under the License.
module GrpcBuildConfig
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-36.dll'
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-37.dll'
end

@ -12,11 +12,11 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 36.0.0
core_version: 37.0.0
csharp_major_version: 2
g_stands_for: gjallarhorn
protobuf_version: 3.24.3
version: 1.60.0-dev
g_stands_for: grand
protobuf_version: 3.25.0
version: 1.61.0-dev
configs:
asan:
CC: clang
@ -149,8 +149,8 @@ defaults:
CFLAGS: -g
COREFLAGS: -fno-exceptions
CPPFLAGS: -g -Wall -Wextra -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp -Ithird_party/re2
-Ithird_party/upb -Isrc/core/ext/upb-generated -Isrc/core/ext/upbdefs-generated
-Ithird_party/utf8_range -Ithird_party/xxhash
-Ithird_party/upb -Isrc/core/ext/upb-gen -Isrc/core/ext/upbdefs-gen -Ithird_party/utf8_range
-Ithird_party/xxhash
LDFLAGS: -g
zlib:
CFLAGS: -fvisibility=hidden

@ -15,6 +15,6 @@
set(UPB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/upb)
set(_gRPC_UPB_INCLUDE_DIR "${UPB_ROOT_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/third_party/utf8_range")
set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-generated" "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upbdefs-generated")
set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-gen" "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upbdefs-gen")
set(_gRPC_UPB_LIBRARIES upb)

848
config.m4 generated

@ -6,8 +6,8 @@ if test "$PHP_GRPC" != "no"; then
dnl # --with-grpc -> add include path
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/core/ext/upb-generated)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/core/ext/upbdefs-generated)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/core/ext/upb-gen)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/core/ext/upbdefs-gen)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/abseil-cpp)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/address_sorting/include)
@ -156,319 +156,319 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/inproc/inproc_plugin.cc \
src/core/ext/transport/inproc/inproc_transport.cc \
src/core/ext/transport/inproc/legacy_inproc_transport.cc \
src/core/ext/upb-generated/envoy/admin/v3/certs.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/clusters.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/config_dump_shared.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/init_dump.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/listeners.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/memory.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/metrics.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/mutex_stats.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/server_info.upb.c \
src/core/ext/upb-generated/envoy/admin/v3/tap.upb.c \
src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c \
src/core/ext/upb-generated/envoy/annotations/resource.upb.c \
src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c \
src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c \
src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c \
src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c \
src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c \
src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c \
src/core/ext/upb-generated/envoy/config/common/matcher/v3/matcher.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/grpc_method_list.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c \
src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.c \
src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c \
src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c \
src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c \
src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c \
src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c \
src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c \
src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.c \
src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c \
src/core/ext/upb-generated/envoy/config/metrics/v3/metrics_service.upb.c \
src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.c \
src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.c \
src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c \
src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c \
src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c \
src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c \
src/core/ext/upb-generated/envoy/config/tap/v3/common.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/datadog.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/dynamic_ot.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/lightstep.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/opencensus.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/opentelemetry.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/service.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/skywalking.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/trace.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/xray.upb.c \
src/core/ext/upb-generated/envoy/config/trace/v3/zipkin.upb.c \
src/core/ext/upb-generated/envoy/data/accesslog/v3/accesslog.upb.c \
src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
src/core/ext/upb-generated/envoy/extensions/http/stateful_session/cookie/v3/cookie.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/common/v3/common.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.c \
src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c \
src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c \
src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c \
src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c \
src/core/ext/upb-generated/envoy/type/http/v3/cookie.upb.c \
src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/filter_state.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/http_inputs.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/status_code_input.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c \
src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c \
src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c \
src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c \
src/core/ext/upb-generated/envoy/type/v3/hash_policy.upb.c \
src/core/ext/upb-generated/envoy/type/v3/http.upb.c \
src/core/ext/upb-generated/envoy/type/v3/http_status.upb.c \
src/core/ext/upb-generated/envoy/type/v3/percent.upb.c \
src/core/ext/upb-generated/envoy/type/v3/range.upb.c \
src/core/ext/upb-generated/envoy/type/v3/ratelimit_strategy.upb.c \
src/core/ext/upb-generated/envoy/type/v3/ratelimit_unit.upb.c \
src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c \
src/core/ext/upb-generated/envoy/type/v3/token_bucket.upb.c \
src/core/ext/upb-generated/google/api/annotations.upb.c \
src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c \
src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c \
src/core/ext/upb-generated/google/api/http.upb.c \
src/core/ext/upb-generated/google/api/httpbody.upb.c \
src/core/ext/upb-generated/google/protobuf/any.upb.c \
src/core/ext/upb-generated/google/protobuf/descriptor.upb.c \
src/core/ext/upb-generated/google/protobuf/duration.upb.c \
src/core/ext/upb-generated/google/protobuf/empty.upb.c \
src/core/ext/upb-generated/google/protobuf/struct.upb.c \
src/core/ext/upb-generated/google/protobuf/timestamp.upb.c \
src/core/ext/upb-generated/google/protobuf/wrappers.upb.c \
src/core/ext/upb-generated/google/rpc/status.upb.c \
src/core/ext/upb-generated/opencensus/proto/trace/v1/trace_config.upb.c \
src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c \
src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c \
src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c \
src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
src/core/ext/upb-generated/udpa/annotations/security.upb.c \
src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c \
src/core/ext/upb-generated/udpa/annotations/status.upb.c \
src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \
src/core/ext/upb-generated/validate/validate.upb.c \
src/core/ext/upb-generated/xds/annotations/v3/migrate.upb.c \
src/core/ext/upb-generated/xds/annotations/v3/security.upb.c \
src/core/ext/upb-generated/xds/annotations/v3/sensitive.upb.c \
src/core/ext/upb-generated/xds/annotations/v3/status.upb.c \
src/core/ext/upb-generated/xds/annotations/v3/versioning.upb.c \
src/core/ext/upb-generated/xds/core/v3/authority.upb.c \
src/core/ext/upb-generated/xds/core/v3/cidr.upb.c \
src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c \
src/core/ext/upb-generated/xds/core/v3/context_params.upb.c \
src/core/ext/upb-generated/xds/core/v3/extension.upb.c \
src/core/ext/upb-generated/xds/core/v3/resource.upb.c \
src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.c \
src/core/ext/upb-generated/xds/core/v3/resource_name.upb.c \
src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.c \
src/core/ext/upb-generated/xds/service/orca/v3/orca.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/cel.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/domain.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/http_inputs.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/ip.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/matcher.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/range.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/regex.upb.c \
src/core/ext/upb-generated/xds/type/matcher/v3/string.upb.c \
src/core/ext/upb-generated/xds/type/v3/cel.upb.c \
src/core/ext/upb-generated/xds/type/v3/range.upb.c \
src/core/ext/upb-generated/xds/type/v3/typed_struct.upb.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/certs.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/clusters.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump_shared.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/init_dump.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/listeners.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/memory.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/metrics.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/mutex_stats.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/server_info.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/admin/v3/tap.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/common/matcher/v3/matcher.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_method_list.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/resolver.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/core/v3/udp_socket_config.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/metrics/v3/metrics_service.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/tap/v3/common.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/datadog.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/dynamic_ot.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/lightstep.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/opencensus.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/opentelemetry.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/service.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/skywalking.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/trace.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/xray.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/config/trace/v3/zipkin.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/data/accesslog/v3/accesslog.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/http/stateful_session/cookie/v3/cookie.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/http/v3/cookie.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/http/v3/path_transformation.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/filter_state.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/http_inputs.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/status_code_input.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/hash_policy.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/http_status.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/ratelimit_strategy.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/ratelimit_unit.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c \
src/core/ext/upbdefs-generated/envoy/type/v3/token_bucket.upbdefs.c \
src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c \
src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.c \
src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.c \
src/core/ext/upbdefs-generated/google/api/http.upbdefs.c \
src/core/ext/upbdefs-generated/google/api/httpbody.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c \
src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c \
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \
src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \
src/core/ext/upbdefs-generated/xds/annotations/v3/migrate.upbdefs.c \
src/core/ext/upbdefs-generated/xds/annotations/v3/security.upbdefs.c \
src/core/ext/upbdefs-generated/xds/annotations/v3/sensitive.upbdefs.c \
src/core/ext/upbdefs-generated/xds/annotations/v3/status.upbdefs.c \
src/core/ext/upbdefs-generated/xds/annotations/v3/versioning.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/cidr.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/context_params.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/extension.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/resource_locator.upbdefs.c \
src/core/ext/upbdefs-generated/xds/core/v3/resource_name.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/cel.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/domain.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/http_inputs.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/ip.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/matcher.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/range.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/regex.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/matcher/v3/string.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/v3/cel.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/v3/range.upbdefs.c \
src/core/ext/upbdefs-generated/xds/type/v3/typed_struct.upbdefs.c \
src/core/ext/upb-gen/envoy/admin/v3/certs.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/clusters.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/config_dump.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/config_dump_shared.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/init_dump.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/listeners.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/memory.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/metrics.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/mutex_stats.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/server_info.upb_minitable.c \
src/core/ext/upb-gen/envoy/admin/v3/tap.upb_minitable.c \
src/core/ext/upb-gen/envoy/annotations/deprecation.upb_minitable.c \
src/core/ext/upb-gen/envoy/annotations/resource.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/accesslog/v3/accesslog.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/cluster/v3/circuit_breaker.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/cluster/v3/filter.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/cluster/v3/outlier_detection.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/address.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/backoff.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/base.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/config_source.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/event_service_config.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/extension.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/grpc_method_list.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/health_check.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/http_uri.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/resolver.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/socket_option.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/substitution_format_string.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/core/v3/udp_socket_config.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/endpoint/v3/load_report.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/listener/v3/api_listener.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/listener/v3/listener_components.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/listener/v3/udp_listener_config.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/overload/v3/overload.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/route/v3/route.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/route/v3/scoped_route.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/tap/v3/common.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/datadog.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/dynamic_ot.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/http_tracer.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/lightstep.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/opencensus.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/service.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/skywalking.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/trace.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/xray.upb_minitable.c \
src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb_minitable.c \
src/core/ext/upb-gen/envoy/data/accesslog/v3/accesslog.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/filters/common/fault/v3/fault.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/filters/http/fault/v3/fault.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/filters/http/router/v3/router.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/http/stateful_session/cookie/v3/cookie.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/cert.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c \
src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c \
src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c \
src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c \
src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c \
src/core/ext/upb-gen/envoy/service/status/v3/csds.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/http_inputs.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/metadata.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/node.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/number.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/path.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/regex.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/status_code_input.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/string.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/struct.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/matcher/v3/value.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/metadata/v3/metadata.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/hash_policy.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/http.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/http_status.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/percent.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/range.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/ratelimit_strategy.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/ratelimit_unit.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/semantic_version.upb_minitable.c \
src/core/ext/upb-gen/envoy/type/v3/token_bucket.upb_minitable.c \
src/core/ext/upb-gen/google/api/annotations.upb_minitable.c \
src/core/ext/upb-gen/google/api/expr/v1alpha1/checked.upb_minitable.c \
src/core/ext/upb-gen/google/api/expr/v1alpha1/syntax.upb_minitable.c \
src/core/ext/upb-gen/google/api/http.upb_minitable.c \
src/core/ext/upb-gen/google/api/httpbody.upb_minitable.c \
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/protobuf/duration.upb_minitable.c \
src/core/ext/upb-gen/google/protobuf/empty.upb_minitable.c \
src/core/ext/upb-gen/google/protobuf/struct.upb_minitable.c \
src/core/ext/upb-gen/google/protobuf/timestamp.upb_minitable.c \
src/core/ext/upb-gen/google/protobuf/wrappers.upb_minitable.c \
src/core/ext/upb-gen/google/rpc/status.upb_minitable.c \
src/core/ext/upb-gen/opencensus/proto/trace/v1/trace_config.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/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c \
src/core/ext/upb-gen/src/proto/grpc/lb/v1/load_balancer.upb_minitable.c \
src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls.upb_minitable.c \
src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls_config.upb_minitable.c \
src/core/ext/upb-gen/udpa/annotations/migrate.upb_minitable.c \
src/core/ext/upb-gen/udpa/annotations/security.upb_minitable.c \
src/core/ext/upb-gen/udpa/annotations/sensitive.upb_minitable.c \
src/core/ext/upb-gen/udpa/annotations/status.upb_minitable.c \
src/core/ext/upb-gen/udpa/annotations/versioning.upb_minitable.c \
src/core/ext/upb-gen/validate/validate.upb_minitable.c \
src/core/ext/upb-gen/xds/annotations/v3/migrate.upb_minitable.c \
src/core/ext/upb-gen/xds/annotations/v3/security.upb_minitable.c \
src/core/ext/upb-gen/xds/annotations/v3/sensitive.upb_minitable.c \
src/core/ext/upb-gen/xds/annotations/v3/status.upb_minitable.c \
src/core/ext/upb-gen/xds/annotations/v3/versioning.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/authority.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/cidr.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/collection_entry.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/context_params.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/extension.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/resource.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/resource_locator.upb_minitable.c \
src/core/ext/upb-gen/xds/core/v3/resource_name.upb_minitable.c \
src/core/ext/upb-gen/xds/data/orca/v3/orca_load_report.upb_minitable.c \
src/core/ext/upb-gen/xds/service/orca/v3/orca.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/domain.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/http_inputs.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/ip.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/range.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/regex.upb_minitable.c \
src/core/ext/upb-gen/xds/type/matcher/v3/string.upb_minitable.c \
src/core/ext/upb-gen/xds/type/v3/cel.upb_minitable.c \
src/core/ext/upb-gen/xds/type/v3/range.upb_minitable.c \
src/core/ext/upb-gen/xds/type/v3/typed_struct.upb_minitable.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/certs.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/clusters.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump_shared.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/init_dump.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/listeners.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/memory.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/metrics.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/mutex_stats.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/server_info.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/admin/v3/tap.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/annotations/deprecation.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/annotations/resource.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/accesslog/v3/accesslog.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3/bootstrap.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/cluster/v3/circuit_breaker.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/cluster/v3/cluster.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/cluster/v3/filter.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/cluster/v3/outlier_detection.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3/matcher.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/address.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/backoff.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/base.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/config_source.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/event_service_config.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/extension.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_method_list.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_service.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/health_check.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/http_uri.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/protocol.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/resolver.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/socket_option.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/substitution_format_string.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/core/v3/udp_socket_config.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/load_report.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/listener/v3/api_listener.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener_components.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/listener/v3/quic_config.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/listener/v3/udp_listener_config.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/metrics/v3/metrics_service.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/metrics/v3/stats.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/overload/v3/overload.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/rbac/v3/rbac.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/route/v3/route.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/route/v3/route_components.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/route/v3/scoped_route.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/tap/v3/common.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/datadog.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/dynamic_ot.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/http_tracer.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/lightstep.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/opencensus.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/opentelemetry.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/service.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/skywalking.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/trace.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/xray.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/config/trace/v3/zipkin.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/data/accesslog/v3/accesslog.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/filters/http/router/v3/router.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/http/stateful_session/cookie/v3/cookie.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/node.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/number.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/path.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/regex.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/status_code_input.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/string.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/struct.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/matcher/v3/value.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/metadata/v3/metadata.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/tracing/v3/custom_tag.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/hash_policy.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/http.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/http_status.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/percent.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/range.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_strategy.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_unit.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/semantic_version.upbdefs.c \
src/core/ext/upbdefs-gen/envoy/type/v3/token_bucket.upbdefs.c \
src/core/ext/upbdefs-gen/google/api/annotations.upbdefs.c \
src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/checked.upbdefs.c \
src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/syntax.upbdefs.c \
src/core/ext/upbdefs-gen/google/api/http.upbdefs.c \
src/core/ext/upbdefs-gen/google/api/httpbody.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/any.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/descriptor.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/duration.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/empty.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/struct.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/timestamp.upbdefs.c \
src/core/ext/upbdefs-gen/google/protobuf/wrappers.upbdefs.c \
src/core/ext/upbdefs-gen/google/rpc/status.upbdefs.c \
src/core/ext/upbdefs-gen/opencensus/proto/trace/v1/trace_config.upbdefs.c \
src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \
src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c \
src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c \
src/core/ext/upbdefs-gen/udpa/annotations/sensitive.upbdefs.c \
src/core/ext/upbdefs-gen/udpa/annotations/status.upbdefs.c \
src/core/ext/upbdefs-gen/udpa/annotations/versioning.upbdefs.c \
src/core/ext/upbdefs-gen/validate/validate.upbdefs.c \
src/core/ext/upbdefs-gen/xds/annotations/v3/migrate.upbdefs.c \
src/core/ext/upbdefs-gen/xds/annotations/v3/security.upbdefs.c \
src/core/ext/upbdefs-gen/xds/annotations/v3/sensitive.upbdefs.c \
src/core/ext/upbdefs-gen/xds/annotations/v3/status.upbdefs.c \
src/core/ext/upbdefs-gen/xds/annotations/v3/versioning.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/authority.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/cidr.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/collection_entry.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/context_params.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/extension.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/resource.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/resource_locator.upbdefs.c \
src/core/ext/upbdefs-gen/xds/core/v3/resource_name.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/cel.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/domain.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/http_inputs.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/ip.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/matcher.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/range.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/regex.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/matcher/v3/string.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.c \
src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.c \
src/core/ext/xds/certificate_provider_store.cc \
src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
src/core/ext/xds/xds_api.cc \
@ -534,12 +534,12 @@ if test "$PHP_GRPC" != "no"; then
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/memory_allocator.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 \
@ -565,6 +565,7 @@ if test "$PHP_GRPC" != "no"; then
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 \
@ -608,6 +609,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gprpp/load_file.cc \
src/core/lib/gprpp/mpscq.cc \
src/core/lib/gprpp/per_cpu.cc \
src/core/lib/gprpp/posix/directory_reader.cc \
src/core/lib/gprpp/posix/env.cc \
src/core/lib/gprpp/posix/stat.cc \
src/core/lib/gprpp/posix/thd.cc \
@ -619,6 +621,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gprpp/time_averaged_stats.cc \
src/core/lib/gprpp/time_util.cc \
src/core/lib/gprpp/validation_errors.cc \
src/core/lib/gprpp/windows/directory_reader.cc \
src/core/lib/gprpp/windows/env.cc \
src/core/lib/gprpp/windows/stat.cc \
src/core/lib/gprpp/windows/thd.cc \
@ -1292,9 +1295,6 @@ if test "$PHP_GRPC" != "no"; then
third_party/re2/util/rune.cc \
third_party/re2/util/strutil.cc \
third_party/upb/upb/base/status.c \
third_party/upb/upb/collections/array.c \
third_party/upb/upb/collections/map.c \
third_party/upb/upb/collections/map_sorter.c \
third_party/upb/upb/hash/common.c \
third_party/upb/upb/json/decode.c \
third_party/upb/upb/json/encode.c \
@ -1305,6 +1305,9 @@ if test "$PHP_GRPC" != "no"; then
third_party/upb/upb/mem/alloc.c \
third_party/upb/upb/mem/arena.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 \
@ -1314,7 +1317,6 @@ if test "$PHP_GRPC" != "no"; then
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/reflection/def_builder.c \
third_party/upb/upb/reflection/def_pool.c \
third_party/upb/upb/reflection/def_type.c \
third_party/upb/upb/reflection/desc_state.c \
@ -1324,6 +1326,8 @@ if test "$PHP_GRPC" != "no"; then
third_party/upb/upb/reflection/extension_range.c \
third_party/upb/upb/reflection/field_def.c \
third_party/upb/upb/reflection/file_def.c \
third_party/upb/upb/reflection/internal/def_builder.c \
third_party/upb/upb/reflection/internal/strdup2.c \
third_party/upb/upb/reflection/message.c \
third_party/upb/upb/reflection/message_def.c \
third_party/upb/upb/reflection/message_reserved_range.c \
@ -1344,7 +1348,7 @@ if test "$PHP_GRPC" != "no"; then
-D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 \
-DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1 \
-DGRPC_XDS_USER_AGENT_NAME_SUFFIX='"\"PHP\""' \
-DGRPC_XDS_USER_AGENT_VERSION_SUFFIX='"\"1.60.0dev\""')
-DGRPC_XDS_USER_AGENT_VERSION_SUFFIX='"\"1.61.0dev\""')
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/backend_metrics)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/census)
@ -1387,106 +1391,106 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/transport)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/inproc)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/admin/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/bootstrap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/cluster/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/common/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/endpoint/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/listener/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/metrics/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/overload/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/route/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/tap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/trace/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/data/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/stateful_session/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/http/stateful_session/cookie/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/common/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/pick_first/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/service/discovery/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/service/load_stats/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/service/status/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/type/http/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/type/metadata/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/type/tracing/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/google/api)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/google/api/expr/v1alpha1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/google/protobuf)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/google/rpc)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/opencensus/proto/trace/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/src/proto/grpc/gcp)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/src/proto/grpc/health/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/src/proto/grpc/lb/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/src/proto/grpc/lookup/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/udpa/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/validate)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/annotations/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/data/orca/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/service/orca/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/admin/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/cluster/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/common/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/listener/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/metrics/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/overload/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/route/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/tap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/trace/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/data/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/stateful_session/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/http/stateful_session/cookie/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/service/discovery/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/service/load_stats/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/service/status/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/type/http/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/type/metadata/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/type/tracing/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/api)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/protobuf)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/rpc)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/opencensus/proto/trace/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/udpa/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/validate)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/xds/annotations/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/xds/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/xds/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/xds/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/admin/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/bootstrap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/cluster/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/common/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/endpoint/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/listener/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/metrics/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/overload/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/route/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/tap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/config/trace/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/data/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/filters/common/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/filters/http/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/filters/http/router/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/http/stateful_session/cookie/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/pick_first/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/ring_hash/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/wrr_locality/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/service/discovery/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/service/load_stats/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/service/status/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/type/http/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/type/metadata/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/type/tracing/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/envoy/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/google/api)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/google/api/expr/v1alpha1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/google/protobuf)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/google/rpc)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/opencensus/proto/trace/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/src/proto/grpc/gcp)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/src/proto/grpc/health/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/src/proto/grpc/lb/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/src/proto/grpc/lookup/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/udpa/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/validate)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/xds/annotations/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/xds/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/xds/data/orca/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/xds/service/orca/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/xds/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-gen/xds/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/admin/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/cluster/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/listener/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/metrics/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/overload/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/route/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/tap/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/config/trace/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/data/accesslog/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/common/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/fault/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/router/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/http/stateful_session/cookie/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/service/discovery/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/service/load_stats/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/service/status/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/type/http/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/type/metadata/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/type/tracing/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/envoy/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/google/api)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/google/api/expr/v1alpha1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/google/protobuf)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/google/rpc)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/opencensus/proto/trace/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/udpa/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/validate)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/xds/annotations/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/xds/core/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/xds/type/matcher/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-gen/xds/type/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/xds)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/address_utils)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/backoff)
@ -1634,7 +1638,6 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/third_party/re2/re2)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/re2/util)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/base)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/collections)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/hash)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/json)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/lex)
@ -1645,6 +1648,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/mini_table)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/mini_table/internal)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/reflection)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/reflection/internal)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/text)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/upb/upb/wire)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/utf8_range)

1118
config.w32 generated

File diff suppressed because it is too large Load Diff

@ -34,10 +34,13 @@ grpc_extra_deps()
## Supported Versions
In general, gRPC supports building with the latest patch release of the two most
recent LTS versions of Bazel. However individual releases may have a broader
gRPC supports building with the latest stable release of Bazel,
as well as the previous major version release for at least 6 months
after it transitions into maintenance mode.
This is consistent with the supported build systems of
[the Google Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
However individual releases may have a broader
compatibility range. The currently supported versions are captured by the
following list:
- [`6.3.2`](https://github.com/bazelbuild/bazel/releases/tag/6.3.2)
- [`5.4.1`](https://github.com/bazelbuild/bazel/releases/tag/5.4.1)
- [`6.4.0`](https://github.com/bazelbuild/bazel/releases/tag/6.4.0)

@ -59,4 +59,5 @@
- 1.57 'g' stands for ['grounded'](https://github.com/grpc/grpc/tree/v1.57.x)
- 1.58 'g' stands for ['goku'](https://github.com/grpc/grpc/tree/v1.58.x)
- 1.59 'g' stands for ['generative'](https://github.com/grpc/grpc/tree/v1.59.x)
- 1.60 'g' stands for ['gjallarhorn'](https://github.com/grpc/grpc/tree/master)
- 1.60 'g' stands for ['gjallarhorn'](https://github.com/grpc/grpc/tree/v1.60.x)
- 1.61 'g' stands for ['grand'](https://github.com/grpc/grpc/tree/master)

@ -62,12 +62,12 @@ DNS](https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md).
Here is an example service config in protobuf form:
```
```textproto
{
// Use round_robin LB policy.
# Use round_robin LB policy.
load_balancing_config: { round_robin: {} }
// This method config applies to method "foo/bar" and to all methods
// of service "baz".
# This method config applies to method "foo/bar" and to all methods
# of service "baz".
method_config: {
name: {
service: "foo"
@ -76,7 +76,7 @@ Here is an example service config in protobuf form:
name: {
service: "baz"
}
// Default timeout for matching methods.
# Default timeout for matching methods.
timeout: {
seconds: 1
nanos: 1
@ -87,7 +87,7 @@ Here is an example service config in protobuf form:
Here is the same example service config in JSON form:
```
```json
{
"loadBalancingConfig": [ { "round_robin": {} } ],
"methodConfig": [

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

@ -0,0 +1,132 @@
# gRPC C++ Debugging Example
This example demonstrates a handful of ways you can debug your gRPC C++ applications.
## Enabling Trace Logs
gRPC allows you to configure more detailed log output for various aspects of gRPC behavior. The tracing log generation might have a large overhead and result in significantly larger log file sizes, especially when you try to trace transport or timer_check. But it is a powerful tool in your debugging toolkit.
### The Most Verbose Logging
Specify environment variables, then run your application:
```
GRPC_VERBOSITY=debug
GRPC_TRACE=all
```
For more granularity, please see
[environment_variables](https://github.com/grpc/grpc/blob/master/doc/environment_variables.md).
### Debug Transport Protocol
```
GRPC_VERBOSITY=debug
GRPC_TRACE=tcp,http,secure_endpoint,transport_security
```
### Debug Connection Behavior
```
GRPC_VERBOSITY=debug
GRPC_TRACE=call_error,connectivity_state,pick_first,round_robin,glb
```
## GDB and other debuggers
`gdb` (and the like) are tools that lets you inspect your application while it is running, view stack traces on exceptions, pause and step through code at specified points or under certain conditions, etc. See https://www.sourceware.org/gdb/
### Inspecting errors
```
bazel build --config=dbg examples/cpp/debugging:crashing_greeter_client
gdb -ex run \
--args ./bazel-bin/examples/cpp/debugging/crashing_greeter_client \
--crash_on_errors=true \
--target=localhork:50051
```
Once the exception is thrown, you can use `bt` to see the stack trace and examine the crash, `info threads` to get the set of threads, etc. See the [GDB documentation](https://sourceware.org/gdb/current/onlinedocs/gdb.html/) for a more complete list of available features and commands.
### Breaking inside a function
After building the application above, this will break inside gRPC generated stub code:
```
gdb -ex 'b helloworld::Greeter::Stub::SayHello' \
-ex run \
--args ./bazel-bin/examples/cpp/debugging/crashing_greeter_client \
--crash_on_errors=true \
--target=localhork:50051
```
## gRPC Admin Interface: Live Channel Tracing
The [gRPC Admin Service](https://github.com/grpc/proposal/blob/master/A38-admin-interface-api.md)
provides a convenient API in each gRPC language to improve the usability of
creating a gRPC server with admin services to expose states in the gRPC library.
This includes channelz, which is a channel tracing feature; it tracks statistics
like how many messages have been sent, how many of them failed, what are the
connected sockets. See the [Channelz design doc](https://github.com/grpc/proposal/blob/master/A14-channelz.md).
### Integrating the gRPC Admin Service Into Your Server
As seen in the `greeter_callback_admin_server` target, you canenable admin services by using the `AddAdminServices` method.
```
grpc::ServerBuilder builder;
grpc::AddAdminServices(&builder);
builder.AddListeningPort(":50051", grpc::ServerCredentials(...));
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
```
### Using grpcdebug
grpcdebug is a tool created to access the metrics from channelz and health services.
#### Installing the grpcdebug tool
The source code is located in a github project
[grpc-ecosystem/grpcdebug](https://github.com/grpc-ecosystem/grpcdebug). You
can either download [the latest built version]
(https://github.com/grpc-ecosystem/grpcdebug/releases/latest) (recommended) or
follow the README.md to build it yourself.
#### Running the grpcdebug tool
##### Usage
`grpcdebug <target address> [flags] channelz <command> [argument]`
| Command | Argument | Description |
| :--------- | :------------------: | :------------------------------------------------ |
| channel | \<channel id or URL> | Display channel states in a human readable way. |
| channels | | Lists client channels for the target application. |
| server | \<server ID> | Displays server state in a human readable way. |
| servers | | Lists servers in a human readable way. |
| socket | \<socket ID> | Displays socket states in a human readable way. |
| subchannel | \<id> | Display subchannel states in human readable way. |
Generally, you will start with either `servers` or `channels` and then work down
to the details
##### Getting overall server info
To begin with, build and run the server binary in the background
```
bazel build --config=dbg examples/cpp/debugging:all
./bazel-bin/examples/cpp/debugging/greeter_callback_server_admin&
```
You can then inspect the server
```bash
grpcdebug localhost:50051 channelz servers
```
This will show you the server ids with their activity
```text
Server ID Listen Addresses Calls(Started/Succeeded/Failed) Last Call Started
1 [[::]:50051] 38/34/3 now
```
For more information about `grpcdebug` features, please see [the grpcdebug documentation](https://github.com/grpc-ecosystem/grpcdebug)

@ -0,0 +1,92 @@
// Copyright 2023 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 <iostream>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(bool, crash_on_errors, false,
"Crash the application on client errors");
ABSL_FLAG(std::string, target, "localhost:50051", "Server address");
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
Status status = stub_->SayHello(&context, request, &reply);
// Act upon the status of the actual RPC.
if (absl::GetFlag(FLAGS_crash_on_errors)) {
assert(status.ok());
}
if (status.ok()) {
return reply.message();
} else {
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
GreeterClient greeter(grpc::CreateChannel(
absl::GetFlag(FLAGS_target), grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}

@ -0,0 +1,86 @@
// Copyright 2023 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 <iostream>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include <grpcpp/ext/admin_services.h>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(uint16_t, port, 50051, "Server port for the service");
using grpc::CallbackServerContext;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerUnaryReactor;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::CallbackService {
ServerUnaryReactor* SayHello(CallbackServerContext* context,
const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
ServerUnaryReactor* reactor = context->DefaultReactor();
reactor->Finish(Status::OK);
return reactor;
}
};
void RunServer(uint16_t port) {
std::string server_address = absl::StrFormat("0.0.0.0:%d", port);
GreeterServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Enable gRPC Admin Services
grpc::AddAdminServices(&builder);
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}

@ -24,3 +24,25 @@ grpc_fuzz_test(
],
deps = ["//src/core:write_size_policy"],
)
grpc_fuzz_test(
name = "hpack_encoder_timeout_test",
srcs = ["hpack_encoder_timeout_test.cc"],
external_deps = [
"absl/random",
"fuzztest",
"fuzztest_main",
"gtest",
],
deps = [
"//:grpc_base",
"//:hpack_encoder",
"//:hpack_parser",
"//:ref_counted_ptr",
"//src/core:arena",
"//src/core:memory_quota",
"//src/core:resource_quota",
"//src/core:slice_buffer",
"//src/core:time",
],
)

@ -0,0 +1,79 @@
// 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.
// Test to verify Fuzztest integration
#include <grpc/event_engine/memory_allocator.h>
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include <memory>
#include <optional>
#include "absl/random/random.h"
#include "fuzztest/fuzztest.h"
#include "gtest/gtest.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/resource_quota/memory_quota.h"
#include "src/core/lib/resource_quota/resource_quota.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.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"
namespace grpc_core {
void EncodeTimeouts(std::vector<uint32_t> timeouts) {
absl::BitGen bitgen;
ScopedTimeCache time_cache;
time_cache.TestOnlySetNow(Timestamp::ProcessEpoch());
hpack_encoder_detail::TimeoutCompressorImpl timeout_compressor;
HPackCompressor compressor;
HPackParser parser;
MemoryAllocator memory_allocator = MemoryAllocator(
ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator("test"));
auto arena = MakeScopedArena(1024, &memory_allocator);
for (size_t i = 0; i < timeouts.size(); i++) {
SliceBuffer encoded;
hpack_encoder_detail::Encoder encoder(&compressor, false, encoded);
timeout_compressor.EncodeWith(
"grpc-timeout",
Timestamp::ProcessEpoch() + Duration::Milliseconds(timeouts[i]),
&encoder);
grpc_metadata_batch b(arena.get());
const uint32_t kMetadataSizeLimit = 3u * 1024 * 1024 * 1024;
parser.BeginFrame(
&b, kMetadataSizeLimit, kMetadataSizeLimit, HPackParser::Boundary::None,
HPackParser::Priority::None,
HPackParser::LogInfo{1, HPackParser::LogInfo::kHeaders, false});
for (size_t j = 0; j < encoded.Count(); j++) {
EXPECT_TRUE(parser
.Parse(encoded.c_slice_at(j), j == encoded.Count() - 1,
bitgen, nullptr)
.ok());
}
auto parsed = b.get(GrpcTimeoutMetadata());
ASSERT_TRUE(parsed.has_value());
EXPECT_GE(*parsed,
Timestamp::ProcessEpoch() + Duration::Milliseconds(timeouts[i]));
EXPECT_LE(*parsed, Timestamp::ProcessEpoch() +
Duration::Milliseconds(timeouts[i]) * 1.05 +
Duration::Milliseconds(1));
}
}
FUZZ_TEST(MyTestSuite, EncodeTimeouts);
} // namespace grpc_core

1750
gRPC-C++.podspec generated

File diff suppressed because it is too large Load Diff

2390
gRPC-Core.podspec generated

File diff suppressed because it is too large Load Diff

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.60.0-dev'
version = '1.61.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.60.0-dev'
version = '1.61.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'

4
gRPC.podspec generated

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.60.0-dev'
version = '1.61.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
@ -32,6 +32,8 @@ Pod::Spec.new do |s|
:tag => "v#{version}",
}
s.resource = 'src/objective-c/PrivacyInfo.xcprivacy'
name = 'GRPCClient'
s.module_name = name
s.header_dir = name

1514
grpc.gemspec generated

File diff suppressed because it is too large Load Diff

807
grpc.gyp generated

File diff suppressed because it is too large Load Diff

@ -79,7 +79,7 @@ namespace experimental {
///
///
/// Blocking EventEngine Callbacks
/// -----------------------------
/// ------------------------------
///
/// Doing blocking work in EventEngine callbacks is generally not advisable.
/// While gRPC's default EventEngine implementations have some capacity to scale
@ -90,6 +90,15 @@ namespace experimental {
/// *Best Practice* : Occasional blocking work may be fine, but we do not
/// recommend running a mostly blocking workload in EventEngine threads.
///
///
/// Thread-safety guarantees
/// ------------------------
///
/// All EventEngine methods are guaranteed to be thread-safe, no external
/// synchronization is required to call any EventEngine method. Please note that
/// this does not apply to application callbacks, which may be run concurrently;
/// application state synchronization must be managed by the application.
///
////////////////////////////////////////////////////////////////////////////////
class EventEngine : public std::enable_shared_from_this<EventEngine> {
public:
@ -246,6 +255,45 @@ class EventEngine : public std::enable_shared_from_this<EventEngine> {
/// values are expected to remain valid for the life of the Endpoint.
virtual const ResolvedAddress& GetPeerAddress() const = 0;
virtual const ResolvedAddress& GetLocalAddress() const = 0;
/// A method which allows users to query whether an Endpoint implementation
/// supports a specified extension. The name of the extension is provided
/// as an input.
///
/// An extension could be any type with a unique string id. Each extension
/// may support additional capabilities and if the Endpoint implementation
/// supports the queried extension, it should return a valid pointer to the
/// extension type.
///
/// E.g., use case of an EventEngine::Endpoint supporting a custom
/// extension.
///
/// class CustomEndpointExtension {
/// public:
/// static constexpr std::string name = "my.namespace.extension_name";
/// void Process() { ... }
/// }
///
///
/// class CustomEndpoint :
/// public EventEngine::Endpoint, CustomEndpointExtension {
/// public:
/// void* QueryExtension(absl::string_view id) override {
/// if (id == CustomEndpointExtension::name) {
/// return static_cast<CustomEndpointExtension*>(this);
/// }
/// return nullptr;
/// }
/// ...
/// }
///
/// auto ext_ =
/// static_cast<CustomEndpointExtension*>(
/// endpoint->QueryExtension(CustomrEndpointExtension::name));
/// if (ext_ != nullptr) { ext_->Process(); }
///
///
virtual void* QueryExtension(absl::string_view /*id*/) { return nullptr; }
};
/// Called when a new connection is established.
@ -405,8 +453,8 @@ class EventEngine : public std::enable_shared_from_this<EventEngine> {
/// Asynchronously executes a task as soon as possible.
///
/// \a Closures scheduled with \a Run cannot be cancelled. The \a closure will
/// not be deleted after it has been run, ownership remains with the caller.
/// \a Closures passed to \a Run cannot be cancelled. The \a closure will not
/// be deleted after it has been run, ownership remains with the caller.
///
/// Implementations must not execute the closure in the calling thread before
/// \a Run returns. For example, if the caller must release a lock before the
@ -415,9 +463,9 @@ class EventEngine : public std::enable_shared_from_this<EventEngine> {
virtual void Run(Closure* closure) = 0;
/// Asynchronously executes a task as soon as possible.
///
/// \a Closures scheduled with \a Run cannot be cancelled. Unlike the
/// overloaded \a Closure alternative, the absl::AnyInvocable version's \a
/// closure will be deleted by the EventEngine after the closure has been run.
/// \a Closures passed to \a Run cannot be cancelled. Unlike the overloaded \a
/// Closure alternative, the absl::AnyInvocable version's \a closure will be
/// deleted by the EventEngine after the closure has been run.
///
/// This version of \a Run may be less performant than the \a Closure version
/// in some scenarios. This overload is useful in situations where performance
@ -453,13 +501,12 @@ class EventEngine : public std::enable_shared_from_this<EventEngine> {
absl::AnyInvocable<void()> closure) = 0;
/// Request cancellation of a task.
///
/// If the associated closure has already been scheduled to run, it will not
/// be cancelled, and this function will return false.
/// If the associated closure cannot be cancelled for any reason, this
/// function will return false.
///
/// If the associated closure has not been scheduled to run, it will be
/// cancelled, and this method will return true. The associated
/// absl::AnyInvocable or \a Closure* will not be called. If the closure type
/// was an absl::AnyInvocable, it will be destroyed before the method returns.
/// If the associated closure can be cancelled, the associated callback will
/// never be run, and this method will return true. If the callback type was
/// an absl::AnyInvocable, it will be destroyed before the method returns.
virtual bool Cancel(TaskHandle handle) = 0;
};

@ -50,6 +50,12 @@ class MemoryAllocatorImpl
/// request.max() inclusively.
virtual size_t Reserve(MemoryRequest request) = 0;
/// Allocate a slice, using MemoryRequest to size the number of returned
/// bytes. For a variable length request, check the returned slice length to
/// verify how much memory was allocated. Takes care of reserving memory for
/// any relevant control structures also.
virtual grpc_slice MakeSlice(MemoryRequest request) = 0;
/// Release some bytes that were previously reserved.
/// If more bytes are released than were reserved, we will have undefined
/// behavior.

@ -134,7 +134,9 @@ class MemoryAllocator {
/// bytes. For a variable length request, check the returned slice length to
/// verify how much memory was allocated. Takes care of reserving memory for
/// any relevant control structures also.
grpc_slice MakeSlice(MemoryRequest request);
grpc_slice MakeSlice(MemoryRequest request) {
return allocator_->MakeSlice(request);
}
/// A C++ allocator for containers of T.
template <typename T>

@ -28,7 +28,6 @@
#include "absl/strings/string_view.h"
#include <grpc/grpc_security.h>
#include <grpc/support/sync.h>
namespace grpc_core {
namespace experimental {
@ -68,6 +67,17 @@ class CrlProvider {
absl::StatusOr<std::shared_ptr<CrlProvider>> CreateStaticCrlProvider(
absl::Span<const std::string> crls);
// Creates a CRL Provider that periodically and asynchronously reloads a
// directory. The refresh_duration minimum is 60 seconds. The
// reload_error_callback provides a way for the user to specifically log or
// otherwise notify of errors during reloading. Since reloading is asynchronous
// and not on the main codepath, the grpc process will continue to run through
// reloading errors, so this mechanism is an important way to provide signals to
// your monitoring and alerting setup.
absl::StatusOr<std::shared_ptr<CrlProvider>> CreateDirectoryReloaderCrlProvider(
absl::string_view directory, std::chrono::seconds refresh_duration,
std::function<void(absl::Status)> reload_error_callback);
} // namespace experimental
} // namespace grpc_core
@ -81,5 +91,4 @@ absl::StatusOr<std::shared_ptr<CrlProvider>> CreateStaticCrlProvider(
void grpc_tls_credentials_options_set_crl_provider(
grpc_tls_credentials_options* options,
std::shared_ptr<grpc_core::experimental::CrlProvider> provider);
#endif /* GRPC_GRPC_CRL_PROVIDER_H */

@ -912,7 +912,10 @@ GRPCAPI void grpc_tls_credentials_options_set_identity_cert_name(
GRPCAPI void grpc_tls_credentials_options_set_cert_request_type(
grpc_tls_credentials_options* options,
grpc_ssl_client_certificate_request_type type);
/**
/** Deprecated in favor of grpc_tls_credentials_options_set_crl_provider. The
* crl provider interface provides a significantly more flexible approach to
* using CRLs. See gRFC A69 for details.
* EXPERIMENTAL API - Subject to change
*
* If set, gRPC will read all hashed x.509 CRL files in the directory and

@ -15,7 +15,7 @@
#ifndef GRPC_IMPL_CHANNEL_ARG_NAMES_H
#define GRPC_IMPL_CHANNEL_ARG_NAMES_H
// IWYU pragma: private, include "third_party/grpc/include/grpc/grpc.h"
// IWYU pragma: private, include <grpc/grpc.h>
// IWYU pragma: friend "src/.*"
// IWYU pragma: friend "test/.*"
@ -384,6 +384,11 @@
* Defaults to 250ms. */
#define GRPC_ARG_HAPPY_EYEBALLS_CONNECTION_ATTEMPT_DELAY_MS \
"grpc.happy_eyeballs_connection_attempt_delay_ms"
/** It accepts a MemoryAllocatorFactory as input and If specified, it forces
* the default event engine to use memory allocators created using the provided
* factory. */
#define GRPC_ARG_EVENT_ENGINE_USE_MEMORY_ALLOCATOR_FACTORY \
"grpc.event_engine_use_memory_allocator_factory"
/** \} */
#endif /* GRPC_IMPL_CHANNEL_ARG_NAMES_H */

@ -74,7 +74,7 @@ struct grpc_slice {
} data;
};
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 7
/** Represents an expandable array of slices, to be interpreted as a
single item. */

@ -99,8 +99,9 @@ class TlsCredentialsOptions {
// verifiers other than the host name verifier is used.
void set_check_call_host(bool check_call_host);
// TODO(zhenlian): This is an experimental API is likely to change in the
// future. Before de-experiementalizing, verify the API is up to date.
// Deprecated in favor of set_crl_provider. The
// crl provider interface provides a significantly more flexible approach to
// using CRLs. See gRFC A69 for details.
// If set, gRPC will read all hashed x.509 CRL files in the directory and
// enforce the CRL files on all TLS handshakes. Only supported for OpenSSL
// version > 1.1.

@ -19,9 +19,9 @@
#define GRPCPP_VERSION_INFO_H
#define GRPC_CPP_VERSION_MAJOR 1
#define GRPC_CPP_VERSION_MINOR 60
#define GRPC_CPP_VERSION_MINOR 61
#define GRPC_CPP_VERSION_PATCH 0
#define GRPC_CPP_VERSION_TAG "dev"
#define GRPC_CPP_VERSION_STRING "1.60.0-dev"
#define GRPC_CPP_VERSION_STRING "1.61.0-dev"
#endif // GRPCPP_VERSION_INFO_H

1518
package.xml generated

File diff suppressed because it is too large Load Diff

@ -16,3 +16,4 @@ xds-protos==0.0.11
opencensus==0.10.0
opencensus-ext-stackdriver==0.8.0
absl-py==1.4.0
googleapis-common-protos==1.61.0

@ -4,7 +4,7 @@
plugins = Cython.Coverage
[build]
build_base=python_build
build_base=pyb
[build_ext]
inplace=1

@ -72,11 +72,9 @@ SSL_INCLUDE = (
os.path.join("third_party", "boringssl-with-bazel", "src", "include"),
)
UPB_INCLUDE = (os.path.join("third_party", "upb"),)
UPB_GRPC_GENERATED_INCLUDE = (
os.path.join("src", "core", "ext", "upb-generated"),
)
UPB_GRPC_GENERATED_INCLUDE = (os.path.join("src", "core", "ext", "upb-gen"),)
UPBDEFS_GRPC_GENERATED_INCLUDE = (
os.path.join("src", "core", "ext", "upbdefs-generated"),
os.path.join("src", "core", "ext", "upbdefs-gen"),
)
UTF8_RANGE_INCLUDE = (os.path.join("third_party", "utf8_range"),)
XXHASH_INCLUDE = (os.path.join("third_party", "xxhash"),)

@ -117,10 +117,12 @@ grpc_cc_library(
"lib/experiments/config.h",
"lib/experiments/experiments.h",
],
defines = select({
defines = select(
{
"//:grpc_experiments_are_final": ["GRPC_EXPERIMENTS_ARE_FINAL"],
"//conditions:default": [],
}),
},
),
external_deps = [
"absl/functional:any_invocable",
"absl/strings",
@ -239,6 +241,27 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "directory_reader",
srcs = [
"lib/gprpp/posix/directory_reader.cc",
"lib/gprpp/windows/directory_reader.cc",
],
hdrs = [
"lib/gprpp/directory_reader.h",
],
external_deps = [
"absl/functional:function_ref",
"absl/status",
"absl/status:statusor",
"absl/strings",
],
deps = [
"//:gpr",
"//:gpr_platform",
],
)
grpc_cc_library(
name = "chunked_vector",
hdrs = ["lib/gprpp/chunked_vector.h"],
@ -270,7 +293,9 @@ grpc_cc_library(
"absl/strings:cord",
"absl/time",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
"upb_mem_lib",
],
language = "c++",
deps = [
@ -397,6 +422,23 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "status_flag",
external_deps = [
"absl/status",
"absl/status:statusor",
"absl/types:optional",
],
language = "c++",
public_hdrs = [
"lib/promise/status_flag.h",
],
deps = [
"promise_status",
"//:gpr_platform",
],
)
grpc_cc_library(
name = "map_pipe",
external_deps = ["absl/status"],
@ -436,6 +478,7 @@ grpc_cc_library(
"arena",
"construct_destruct",
"context",
"poll",
"promise_factory",
"promise_trace",
"ref_counted",
@ -832,6 +875,25 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "inter_activity_latch",
external_deps = [
"absl/base:core_headers",
"absl/strings",
],
language = "c++",
public_hdrs = [
"lib/promise/inter_activity_latch.h",
],
deps = [
"activity",
"poll",
"promise_trace",
"wait_set",
"//:gpr",
],
)
grpc_cc_library(
name = "interceptor_list",
hdrs = [
@ -881,6 +943,19 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "promise_mutex",
hdrs = [
"lib/promise/promise_mutex.h",
],
language = "c++",
deps = [
"activity",
"poll",
"//:gpr",
],
)
grpc_cc_library(
name = "inter_activity_pipe",
hdrs = [
@ -1088,9 +1163,6 @@ grpc_cc_library(
grpc_cc_library(
name = "event_engine_memory_allocator",
srcs = [
"lib/event_engine/memory_allocator.cc",
],
hdrs = [
"//:include/grpc/event_engine/internal/memory_allocator_impl.h",
"//:include/grpc/event_engine/memory_allocator.h",
@ -1100,7 +1172,6 @@ grpc_cc_library(
language = "c++",
deps = [
"slice",
"slice_refcount",
"//:gpr_platform",
],
)
@ -1146,6 +1217,7 @@ grpc_cc_library(
"race",
"resource_quota_trace",
"seq",
"slice_refcount",
"time",
"useful",
"//:gpr",
@ -1435,9 +1507,7 @@ grpc_cc_library(
hdrs = [
"lib/event_engine/forkable.h",
],
external_deps = ["absl/base:core_headers"],
deps = [
"no_destruct",
"//:config_vars",
"//:gpr",
"//:gpr_platform",
@ -1467,6 +1537,18 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "event_engine_query_extensions",
hdrs = [
"lib/event_engine/query_extensions.h",
],
external_deps = ["absl/strings"],
deps = [
"//:event_engine_base_hdrs",
"//:gpr_platform",
],
)
grpc_cc_library(
name = "event_engine_work_queue",
hdrs = [
@ -1580,9 +1662,9 @@ grpc_cc_library(
"event_engine_trace",
"event_engine_work_queue",
"forkable",
"no_destruct",
"notification",
"time",
"useful",
"//:backoff",
"//:event_engine_base_hdrs",
"//:gpr",
@ -1643,6 +1725,7 @@ grpc_cc_library(
],
deps = [
"event_engine_poller",
"forkable",
"posix_event_engine_closure",
"//:event_engine_base_hdrs",
"//:gpr_platform",
@ -1775,7 +1858,6 @@ grpc_cc_library(
deps = [
"event_engine_poller",
"event_engine_time_util",
"forkable",
"iomgr_port",
"posix_event_engine_closure",
"posix_event_engine_event_poller",
@ -1813,7 +1895,6 @@ grpc_cc_library(
"common_event_engine_closures",
"event_engine_poller",
"event_engine_time_util",
"forkable",
"iomgr_port",
"posix_event_engine_closure",
"posix_event_engine_event_poller",
@ -1838,7 +1919,9 @@ grpc_cc_library(
],
external_deps = ["absl/strings"],
deps = [
"forkable",
"iomgr_port",
"no_destruct",
"posix_event_engine_event_poller",
"posix_event_engine_poller_posix_epoll1",
"posix_event_engine_poller_posix_poll",
@ -2052,8 +2135,11 @@ grpc_cc_library(
"event_engine_thread_pool",
"event_engine_trace",
"event_engine_utils",
"forkable",
"init_internally",
"iomgr_port",
"native_dns_resolver",
"no_destruct",
"posix_event_engine_base_hdrs",
"posix_event_engine_closure",
"posix_event_engine_endpoint",
@ -2063,7 +2149,9 @@ grpc_cc_library(
"posix_event_engine_tcp_socket_utils",
"posix_event_engine_timer",
"posix_event_engine_timer_manager",
"ref_counted_dns_resolver_interface",
"useful",
"//:config_vars",
"//:event_engine_base_hdrs",
"//:gpr",
"//:grpc_trace",
@ -2081,6 +2169,7 @@ grpc_cc_library(
"absl/strings",
],
deps = [
"ares_resolver",
"channel_args_endpoint_config",
"common_event_engine_closures",
"error",
@ -2090,6 +2179,7 @@ grpc_cc_library(
"event_engine_trace",
"event_engine_utils",
"init_internally",
"iomgr_port",
"posix_event_engine_timer_manager",
"time",
"windows_endpoint",
@ -2290,7 +2380,8 @@ grpc_cc_library(
srcs = ["lib/event_engine/default_event_engine_factory.cc"],
hdrs = ["lib/event_engine/default_event_engine_factory.h"],
external_deps = ["absl/memory"],
select_deps = [{
select_deps = [
{
"//:windows": ["windows_event_engine"],
"//:windows_msvc": ["windows_event_engine"],
"//:windows_other": ["windows_event_engine"],
@ -2310,7 +2401,8 @@ grpc_cc_library(
"//:tvos": ["cf_event_engine"],
"//:watchos": ["cf_event_engine"],
"//conditions:default": ["posix_event_engine"],
}],
},
],
deps = [
"//:event_engine_base_hdrs",
"//:gpr_platform",
@ -2380,16 +2472,53 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "ref_counted_dns_resolver_interface",
hdrs = ["lib/event_engine/ref_counted_dns_resolver_interface.h"],
external_deps = ["absl/strings"],
deps = [
"//:event_engine_base_hdrs",
"//:gpr_platform",
"//:orphanable",
],
)
grpc_cc_library(
name = "native_dns_resolver",
srcs = [
"lib/event_engine/posix_engine/native_dns_resolver.cc",
],
hdrs = [
"lib/event_engine/posix_engine/native_dns_resolver.h",
],
external_deps = [
"absl/functional:any_invocable",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/strings:str_format",
],
deps = [
"iomgr_port",
"ref_counted_dns_resolver_interface",
"useful",
"//:event_engine_base_hdrs",
"//:gpr",
],
)
grpc_cc_library(
name = "ares_resolver",
srcs = [
"lib/event_engine/ares_resolver.cc",
"lib/event_engine/windows/grpc_polled_fd_windows.cc",
],
hdrs = [
"lib/event_engine/ares_resolver.h",
"lib/event_engine/grpc_polled_fd.h",
"lib/event_engine/nameser.h",
"lib/event_engine/posix_engine/grpc_polled_fd_posix.h",
"lib/event_engine/windows/grpc_polled_fd_windows.h",
],
external_deps = [
"absl/base:core_headers",
@ -2405,6 +2534,7 @@ grpc_cc_library(
"cares",
],
deps = [
"common_event_engine_closures",
"error",
"event_engine_time_util",
"grpc_sockaddr",
@ -2412,7 +2542,10 @@ grpc_cc_library(
"posix_event_engine_closure",
"posix_event_engine_event_poller",
"posix_event_engine_tcp_socket_utils",
"ref_counted_dns_resolver_interface",
"resolved_address",
"slice",
"windows_iocp",
"//:debug_location",
"//:event_engine_base_hdrs",
"//:gpr",
@ -3082,15 +3215,23 @@ grpc_cc_library(
"lib/security/credentials/tls/grpc_tls_crl_provider.h",
],
external_deps = [
"absl/base:core_headers",
"absl/container:flat_hash_map",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/types:optional",
"absl/types:span",
"libcrypto",
"libssl",
],
deps = [
"default_event_engine",
"directory_reader",
"load_file",
"slice",
"time",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
],
@ -4047,13 +4188,16 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/container:inlined_vector",
"absl/functional:function_ref",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/strings:str_format",
"absl/types:optional",
"absl/types:variant",
"upb_base_lib",
"upb_lib",
"upb_mem_lib",
],
language = "c++",
deps = [
@ -4158,6 +4302,7 @@ grpc_cc_library(
"absl/strings",
"absl/strings:str_format",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
],
language = "c++",
@ -4209,7 +4354,7 @@ grpc_cc_library(
],
external_deps = [
"absl/strings",
"upb_lib",
"upb_base_lib",
],
language = "c++",
deps = ["//:gpr_platform"],
@ -4284,7 +4429,9 @@ grpc_cc_library(
"absl/types:optional",
"absl/types:span",
"absl/types:variant",
"upb_base_lib",
"upb_lib",
"upb_mem_lib",
"upb_textformat_lib",
"upb_json_lib",
"re2",
@ -4569,6 +4716,7 @@ grpc_cc_library(
"ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc",
],
external_deps = [
"absl/functional:function_ref",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -4591,6 +4739,7 @@ grpc_cc_library(
"no_destruct",
"pollset_set",
"ref_counted_string",
"resolved_address",
"validation_errors",
"//:channel_arg_names",
"//:config",
@ -4739,6 +4888,7 @@ grpc_cc_library(
"ext/filters/client_channel/lb_policy/address_filtering.h",
],
external_deps = [
"absl/functional:function_ref",
"absl/status:statusor",
"absl/strings",
],
@ -4747,6 +4897,7 @@ grpc_cc_library(
"channel_args",
"ref_counted",
"ref_counted_string",
"resolved_address",
"//:endpoint_addresses",
"//:gpr_platform",
"//:ref_counted_ptr",
@ -4768,6 +4919,7 @@ grpc_cc_library(
"absl/status:statusor",
"absl/strings",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
],
language = "c++",
@ -4815,6 +4967,7 @@ grpc_cc_library(
"lb_policy",
"subchannel_interface",
"//:debug_location",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_base",
"//:ref_counted_ptr",
@ -4832,7 +4985,7 @@ grpc_cc_library(
"ext/filters/client_channel/lb_policy/endpoint_list.h",
],
external_deps = [
"absl/functional:any_invocable",
"absl/functional:function_ref",
"absl/status",
"absl/status:statusor",
"absl/types:optional",
@ -5226,6 +5379,7 @@ grpc_cc_library(
],
external_deps = [
"absl/base:core_headers",
"absl/functional:function_ref",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -5327,6 +5481,7 @@ grpc_cc_library(
"absl/status:statusor",
"absl/strings",
"absl/types:optional",
"upb_base_lib",
"upb_lib",
],
language = "c++",
@ -5388,8 +5543,12 @@ grpc_cc_library(
grpc_cc_library(
name = "service_config_helper",
srcs = ["ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc"],
hdrs = ["ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h"],
srcs = [
"ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc",
],
hdrs = [
"ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h",
],
external_deps = [
"absl/status:statusor",
"absl/strings",
@ -5409,8 +5568,12 @@ grpc_cc_library(
grpc_cc_library(
name = "grpc_resolver_dns_event_engine",
srcs = ["ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc"],
hdrs = ["ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h"],
srcs = [
"ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc",
],
hdrs = [
"ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h",
],
external_deps = [
"absl/base:core_headers",
"absl/cleanup",
@ -5675,7 +5838,6 @@ grpc_cc_library(
hdrs = [
"ext/transport/chttp2/transport/hpack_encoder_table.h",
],
external_deps = ["absl/container:inlined_vector"],
language = "c++",
deps = [
"hpack_constants",
@ -6021,6 +6183,7 @@ grpc_cc_library(
"arena",
"bitset",
"chaotic_good_frame_header",
"context",
"no_destruct",
"slice",
"slice_buffer",
@ -6183,29 +6346,43 @@ grpc_cc_library(
],
external_deps = [
"absl/base:core_headers",
"absl/random",
"absl/random:bit_gen_ref",
"absl/status",
"absl/status:statusor",
"absl/types:optional",
"absl/types:variant",
],
language = "c++",
deps = [
"activity",
"arena",
"chaotic_good_frame",
"chaotic_good_frame_header",
"context",
"event_engine_wakeup_scheduler",
"for_each",
"grpc_promise_endpoint",
"join",
"if",
"inter_activity_pipe",
"loop",
"match",
"memory_quota",
"mpsc",
"pipe",
"seq",
"poll",
"resource_quota",
"slice",
"slice_buffer",
"try_join",
"try_seq",
"//:exec_ctx",
"//:gpr",
"//:gpr_platform",
"//:grpc_base",
"//:hpack_encoder",
"//:hpack_parser",
"//:ref_counted_ptr",
],
)
@ -6338,7 +6515,9 @@ grpc_upb_proto_library(
grpc_upb_proto_library(
name = "envoy_extensions_load_balancing_policies_client_side_weighted_round_robin_upb",
deps = ["@envoy_api//envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3:pkg"],
deps = [
"@envoy_api//envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3:pkg",
],
)
grpc_upb_proto_library(
@ -6358,12 +6537,16 @@ grpc_upb_proto_library(
grpc_upb_proto_library(
name = "envoy_extensions_filters_network_http_connection_manager_upb",
deps = ["@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg"],
deps = [
"@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg",
],
)
grpc_upb_proto_reflection_library(
name = "envoy_extensions_filters_network_http_connection_manager_upbdefs",
deps = ["@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg"],
deps = [
"@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg",
],
)
grpc_upb_proto_library(
@ -6490,14 +6673,20 @@ WELL_KNOWN_PROTO_TARGETS = [
"wrappers",
]
[grpc_upb_proto_library(
[
grpc_upb_proto_library(
name = "protobuf_" + target + "_upb",
deps = ["@com_google_protobuf//:" + target + "_proto"],
) for target in WELL_KNOWN_PROTO_TARGETS]
)
for target in WELL_KNOWN_PROTO_TARGETS
]
[grpc_upb_proto_reflection_library(
[
grpc_upb_proto_reflection_library(
name = "protobuf_" + target + "_upbdefs",
deps = ["@com_google_protobuf//:" + target + "_proto"],
) for target in WELL_KNOWN_PROTO_TARGETS]
)
for target in WELL_KNOWN_PROTO_TARGETS
]
grpc_generate_one_off_internal_targets()

@ -315,6 +315,14 @@ class ClientChannel::PromiseBasedCallData : public ClientChannel::CallData {
public:
explicit PromiseBasedCallData(ClientChannel* chand) : chand_(chand) {}
~PromiseBasedCallData() override {
if (was_queued_ && client_initial_metadata_ != nullptr) {
MutexLock lock(&chand_->resolution_mu_);
RemoveCallFromResolverQueuedCallsLocked();
chand_->resolver_queued_calls_.erase(this);
}
}
ArenaPromise<absl::StatusOr<CallArgs>> MakeNameResolutionPromise(
CallArgs call_args) {
pollent_ = NowOrNever(call_args.polling_entity->WaitAndCopy()).value();
@ -399,6 +407,7 @@ class ClientChannel::PromiseBasedCallData : public ClientChannel::CallData {
const grpc_channel_filter ClientChannel::kFilterVtableWithPromises = {
ClientChannel::FilterBasedCallData::StartTransportStreamOpBatch,
ClientChannel::MakeCallPromise,
/* init_call: */ nullptr,
ClientChannel::StartTransportOp,
sizeof(ClientChannel::FilterBasedCallData),
ClientChannel::FilterBasedCallData::Init,
@ -415,6 +424,7 @@ const grpc_channel_filter ClientChannel::kFilterVtableWithPromises = {
const grpc_channel_filter ClientChannel::kFilterVtableWithoutPromises = {
ClientChannel::FilterBasedCallData::StartTransportStreamOpBatch,
nullptr,
/* init_call: */ nullptr,
ClientChannel::StartTransportOp,
sizeof(ClientChannel::FilterBasedCallData),
ClientChannel::FilterBasedCallData::Init,
@ -562,6 +572,7 @@ class DynamicTerminationFilter::CallData {
const grpc_channel_filter DynamicTerminationFilter::kFilterVtable = {
DynamicTerminationFilter::CallData::StartTransportStreamOpBatch,
DynamicTerminationFilter::MakeCallPromise,
/* init_call: */ nullptr,
DynamicTerminationFilter::StartTransportOp,
sizeof(DynamicTerminationFilter::CallData),
DynamicTerminationFilter::CallData::Init,
@ -1599,7 +1610,12 @@ absl::Status ClientChannel::CreateOrUpdateLbPolicyLocked(
Resolver::Result result) {
// Construct update.
LoadBalancingPolicy::UpdateArgs update_args;
update_args.addresses = std::move(result.addresses);
if (!result.addresses.ok()) {
update_args.addresses = result.addresses.status();
} else {
update_args.addresses = std::make_shared<EndpointAddressesListIterator>(
std::move(*result.addresses));
}
update_args.config = std::move(lb_policy_config);
update_args.resolution_note = std::move(result.resolution_note);
// Remove the config selector from channel args so that we're not holding

@ -20,11 +20,13 @@
#include <stddef.h>
#include <algorithm>
#include <utility>
#include "absl/functional/function_ref.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/resolved_address.h"
namespace grpc_core {
@ -43,20 +45,26 @@ int HierarchicalPathArg::ChannelArgsCompare(const HierarchicalPathArg* a,
return 0;
}
absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
const absl::StatusOr<EndpointAddressesList>& addresses) {
if (!addresses.ok()) return addresses.status();
HierarchicalAddressMap result;
namespace {
class HierarchicalAddressIterator : public EndpointAddressesIterator {
public:
HierarchicalAddressIterator(
std::shared_ptr<EndpointAddressesIterator> parent_it,
RefCountedStringValue child_name)
: parent_it_(std::move(parent_it)), child_name_(std::move(child_name)) {}
void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
const override {
RefCountedPtr<HierarchicalPathArg> remaining_path_attr;
for (const EndpointAddresses& endpoint_addresses : *addresses) {
const auto* path_arg =
endpoint_addresses.args().GetObject<HierarchicalPathArg>();
if (path_arg == nullptr) continue;
parent_it_->ForEach([&](const EndpointAddresses& endpoint) {
const auto* path_arg = endpoint.args().GetObject<HierarchicalPathArg>();
if (path_arg == nullptr) return;
const std::vector<RefCountedStringValue>& path = path_arg->path();
auto it = path.begin();
if (it == path.end()) continue;
EndpointAddressesList& target_list = result[*it];
ChannelArgs args = endpoint_addresses.args();
if (it == path.end()) return;
if (*it != child_name_) return;
ChannelArgs args = endpoint.args();
++it;
if (it != path.end()) {
std::vector<RefCountedStringValue> remaining_path(it, path.end());
@ -67,8 +75,33 @@ absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
}
args = args.SetObject(remaining_path_attr);
}
target_list.emplace_back(endpoint_addresses.addresses(), args);
callback(EndpointAddresses(endpoint.addresses(), args));
});
}
private:
std::shared_ptr<EndpointAddressesIterator> parent_it_;
RefCountedStringValue child_name_;
};
} // namespace
absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses) {
if (!addresses.ok()) return addresses.status();
HierarchicalAddressMap result;
(*addresses)->ForEach([&](const EndpointAddresses& endpoint) {
const auto* path_arg = endpoint.args().GetObject<HierarchicalPathArg>();
if (path_arg == nullptr) return;
const std::vector<RefCountedStringValue>& path = path_arg->path();
auto it = path.begin();
if (it == path.end()) return;
auto& target_list = result[*it];
if (target_list == nullptr) {
target_list =
std::make_shared<HierarchicalAddressIterator>(*addresses, *it);
}
});
return result;
}

@ -20,6 +20,7 @@
#include <grpc/support/port_platform.h>
#include <map>
#include <memory>
#include <utility>
#include <vector>
@ -105,12 +106,12 @@ class HierarchicalPathArg : public RefCounted<HierarchicalPathArg> {
// A map from the next path element to the endpoint addresses that fall
// under that path element.
using HierarchicalAddressMap =
std::map<RefCountedStringValue, EndpointAddressesList,
std::map<RefCountedStringValue, std::shared_ptr<EndpointAddressesIterator>,
RefCountedStringValueLessThan>;
// Splits up the addresses into a separate list for each child.
absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
const absl::StatusOr<EndpointAddressesList>& addresses);
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses);
} // namespace grpc_core

@ -98,7 +98,7 @@ class ChildPolicyHandler::Helper
: parent()->child_policy_.get();
if (child_ != latest_child_policy) return;
if (GRPC_TRACE_FLAG_ENABLED(*(parent()->tracer_))) {
gpr_log(GPR_INFO, "[child_policy_handler %p] started name re-resolving",
gpr_log(GPR_INFO, "[child_policy_handler %p] requesting re-resolution",
parent());
}
parent()->channel_control_helper()->RequestReresolution();

@ -118,7 +118,7 @@ void EndpointList::Endpoint::Init(
GPR_ASSERT(config.ok());
// Update child policy.
LoadBalancingPolicy::UpdateArgs update_args;
update_args.addresses.emplace().emplace_back(addresses);
update_args.addresses = std::make_shared<SingleEndpointIterator>(addresses);
update_args.args = child_args;
update_args.config = std::move(*config);
// TODO(roth): If the child reports a non-OK status with the update,
@ -163,15 +163,16 @@ RefCountedPtr<SubchannelInterface> EndpointList::Endpoint::CreateSubchannel(
//
void EndpointList::Init(
const EndpointAddressesList& endpoints, const ChannelArgs& args,
absl::AnyInvocable<OrphanablePtr<Endpoint>(RefCountedPtr<EndpointList>,
EndpointAddressesIterator* endpoints, const ChannelArgs& args,
absl::FunctionRef<OrphanablePtr<Endpoint>(RefCountedPtr<EndpointList>,
const EndpointAddresses&,
const ChannelArgs&)>
create_endpoint) {
for (const EndpointAddresses& addresses : endpoints) {
if (endpoints == nullptr) return;
endpoints->ForEach([&](const EndpointAddresses& endpoint) {
endpoints_.push_back(
create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), addresses, args));
}
create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), endpoint, args));
});
}
void EndpointList::ResetBackoffLocked() {

@ -25,7 +25,7 @@
#include <utility>
#include <vector>
#include "absl/functional/any_invocable.h"
#include "absl/functional/function_ref.h"
#include "absl/status/status.h"
#include "absl/types/optional.h"
@ -53,7 +53,7 @@ namespace grpc_core {
class MyEndpointList : public EndpointList {
public:
MyEndpointList(RefCountedPtr<MyLbPolicy> lb_policy,
const EndpointAddressesList& endpoints,
EndpointAddressesIterator* endpoints,
const ChannelArgs& args)
: EndpointList(std::move(lb_policy),
GRPC_TRACE_FLAG_ENABLED(grpc_my_tracer)
@ -184,8 +184,8 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
EndpointList(RefCountedPtr<LoadBalancingPolicy> policy, const char* tracer)
: policy_(std::move(policy)), tracer_(tracer) {}
void Init(const EndpointAddressesList& endpoints, const ChannelArgs& args,
absl::AnyInvocable<OrphanablePtr<Endpoint>(
void Init(EndpointAddressesIterator* endpoints, const ChannelArgs& args,
absl::FunctionRef<OrphanablePtr<Endpoint>(
RefCountedPtr<EndpointList>, const EndpointAddresses&,
const ChannelArgs&)>
create_endpoint);

@ -72,6 +72,7 @@
#include <vector>
#include "absl/container/inlined_vector.h"
#include "absl/functional/function_ref.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
@ -384,9 +385,9 @@ class GrpcLb : public LoadBalancingPolicy {
// Returns a text representation suitable for logging.
std::string AsText() const;
// Extracts all non-drop entries into an EndpointAddressesList.
EndpointAddressesList GetServerAddressList(
GrpcLbClientStats* client_stats) const;
// Extracts all non-drop entries into an EndpointAddressesIterator.
std::shared_ptr<EndpointAddressesIterator> GetServerAddressList(
GrpcLbClientStats* client_stats);
// Returns true if the serverlist contains at least one drop entry and
// no backend address entries.
@ -400,6 +401,8 @@ class GrpcLb : public LoadBalancingPolicy {
const char* ShouldDrop();
private:
class AddressIterator;
std::vector<GrpcLbServer> serverlist_;
// Accessed from the picker, so needs synchronization.
@ -504,6 +507,8 @@ class GrpcLb : public LoadBalancingPolicy {
RefCountedPtr<GrpcLb> parent_;
};
class NullLbTokenEndpointIterator;
void ShutdownLocked() override;
// Helper functions used in UpdateLocked().
@ -569,7 +574,8 @@ class GrpcLb : public LoadBalancingPolicy {
// Whether we're in fallback mode.
bool fallback_mode_ = false;
// The backend addresses from the resolver.
absl::StatusOr<EndpointAddressesList> fallback_backend_addresses_;
absl::StatusOr<std::shared_ptr<NullLbTokenEndpointIterator>>
fallback_backend_addresses_;
// The last resolution note from our parent.
// To be passed to child policy when fallback_backend_addresses_ is empty.
std::string resolution_note_;
@ -594,11 +600,30 @@ class GrpcLb : public LoadBalancingPolicy {
};
//
// GrpcLb::Serverlist
// GrpcLb::Serverlist::AddressIterator
//
bool GrpcLb::Serverlist::operator==(const Serverlist& other) const {
return serverlist_ == other.serverlist_;
bool IsServerValid(const GrpcLbServer& server, size_t idx, bool log) {
if (server.drop) return false;
if (GPR_UNLIKELY(server.port >> 16 != 0)) {
if (log) {
gpr_log(GPR_ERROR,
"Invalid port '%d' at index %" PRIuPTR
" of serverlist. Ignoring.",
server.port, idx);
}
return false;
}
if (GPR_UNLIKELY(server.ip_size != 4 && server.ip_size != 16)) {
if (log) {
gpr_log(GPR_ERROR,
"Expected IP to be 4 or 16 bytes, got %d at index %" PRIuPTR
" of serverlist. Ignoring",
server.ip_size, idx);
}
return false;
}
return true;
}
void ParseServer(const GrpcLbServer& server, grpc_resolved_address* addr) {
@ -623,6 +648,53 @@ void ParseServer(const GrpcLbServer& server, grpc_resolved_address* addr) {
}
}
class GrpcLb::Serverlist::AddressIterator : public EndpointAddressesIterator {
public:
AddressIterator(RefCountedPtr<Serverlist> serverlist,
RefCountedPtr<GrpcLbClientStats> client_stats)
: serverlist_(std::move(serverlist)),
client_stats_(std::move(client_stats)) {}
void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
const override {
for (size_t i = 0; i < serverlist_->serverlist_.size(); ++i) {
const GrpcLbServer& server = serverlist_->serverlist_[i];
if (!IsServerValid(server, i, false)) continue;
// Address processing.
grpc_resolved_address addr;
ParseServer(server, &addr);
// LB token processing.
const size_t lb_token_length = strnlen(
server.load_balance_token, GPR_ARRAY_SIZE(server.load_balance_token));
std::string lb_token(server.load_balance_token, lb_token_length);
if (lb_token.empty()) {
auto addr_uri = grpc_sockaddr_to_uri(&addr);
gpr_log(GPR_INFO,
"Missing LB token for backend address '%s'. The empty token "
"will be used instead",
addr_uri.ok() ? addr_uri->c_str()
: addr_uri.status().ToString().c_str());
}
// Return address with a channel arg containing LB token and stats object.
callback(EndpointAddresses(
addr, ChannelArgs().SetObject(MakeRefCounted<TokenAndClientStatsArg>(
std::move(lb_token), client_stats_))));
}
}
private:
RefCountedPtr<Serverlist> serverlist_;
RefCountedPtr<GrpcLbClientStats> client_stats_;
};
//
// GrpcLb::Serverlist
//
bool GrpcLb::Serverlist::operator==(const Serverlist& other) const {
return serverlist_ == other.serverlist_;
}
std::string GrpcLb::Serverlist::AsText() const {
std::vector<std::string> entries;
for (size_t i = 0; i < serverlist_.size(); ++i) {
@ -642,59 +714,12 @@ std::string GrpcLb::Serverlist::AsText() const {
return absl::StrJoin(entries, "");
}
bool IsServerValid(const GrpcLbServer& server, size_t idx, bool log) {
if (server.drop) return false;
if (GPR_UNLIKELY(server.port >> 16 != 0)) {
if (log) {
gpr_log(GPR_ERROR,
"Invalid port '%d' at index %" PRIuPTR
" of serverlist. Ignoring.",
server.port, idx);
}
return false;
}
if (GPR_UNLIKELY(server.ip_size != 4 && server.ip_size != 16)) {
if (log) {
gpr_log(GPR_ERROR,
"Expected IP to be 4 or 16 bytes, got %d at index %" PRIuPTR
" of serverlist. Ignoring",
server.ip_size, idx);
}
return false;
}
return true;
}
// Returns addresses extracted from the serverlist.
EndpointAddressesList GrpcLb::Serverlist::GetServerAddressList(
GrpcLbClientStats* client_stats) const {
std::shared_ptr<EndpointAddressesIterator>
GrpcLb::Serverlist::GetServerAddressList(GrpcLbClientStats* client_stats) {
RefCountedPtr<GrpcLbClientStats> stats;
if (client_stats != nullptr) stats = client_stats->Ref();
EndpointAddressesList endpoints;
for (size_t i = 0; i < serverlist_.size(); ++i) {
const GrpcLbServer& server = serverlist_[i];
if (!IsServerValid(server, i, false)) continue;
// Address processing.
grpc_resolved_address addr;
ParseServer(server, &addr);
// LB token processing.
const size_t lb_token_length = strnlen(
server.load_balance_token, GPR_ARRAY_SIZE(server.load_balance_token));
std::string lb_token(server.load_balance_token, lb_token_length);
if (lb_token.empty()) {
auto addr_uri = grpc_sockaddr_to_uri(&addr);
gpr_log(GPR_INFO,
"Missing LB token for backend address '%s'. The empty token will "
"be used instead",
addr_uri.ok() ? addr_uri->c_str()
: addr_uri.status().ToString().c_str());
}
// Add address with a channel arg containing LB token and stats object.
endpoints.emplace_back(
addr, ChannelArgs().SetObject(MakeRefCounted<TokenAndClientStatsArg>(
std::move(lb_token), stats)));
}
return endpoints;
return std::make_shared<AddressIterator>(Ref(), std::move(stats));
}
bool GrpcLb::Serverlist::ContainsAllDropEntries() const {
@ -841,14 +866,10 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
void GrpcLb::Helper::RequestReresolution() {
if (parent()->shutting_down_) return;
// If we are talking to a balancer, we expect to get updated addresses
// from the balancer, so we can ignore the re-resolution request from
// the child policy. Otherwise, pass the re-resolution request up to the
// channel.
if (parent()->lb_calld_ == nullptr ||
!parent()->lb_calld_->seen_initial_response()) {
// Ignore if we're not in fallback mode, because if we got the backend
// addresses from the balancer, re-resolving is not going to fix it.
if (!parent()->fallback_mode_) return;
parent()->channel_control_helper()->RequestReresolution();
}
}
//
@ -1507,21 +1528,45 @@ void GrpcLb::ResetBackoffLocked() {
}
}
// Endpoint iterator wrapper to add null LB token attribute.
class GrpcLb::NullLbTokenEndpointIterator : public EndpointAddressesIterator {
public:
explicit NullLbTokenEndpointIterator(
std::shared_ptr<EndpointAddressesIterator> parent_it)
: parent_it_(std::move(parent_it)) {}
void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
const override {
parent_it_->ForEach([&](const EndpointAddresses& endpoint) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
gpr_log(GPR_INFO, "[grpclb %p] fallback address: %s", this,
endpoint.ToString().c_str());
}
callback(EndpointAddresses(endpoint.addresses(),
endpoint.args().SetObject(empty_token_)));
});
}
private:
std::shared_ptr<EndpointAddressesIterator> parent_it_;
RefCountedPtr<TokenAndClientStatsArg> empty_token_ =
MakeRefCounted<TokenAndClientStatsArg>("", nullptr);
};
absl::Status GrpcLb::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
gpr_log(GPR_INFO, "[grpclb %p] received update", this);
}
const bool is_initial_update = lb_channel_ == nullptr;
config_ = args.config;
GPR_ASSERT(config_ != nullptr);
args_ = std::move(args.args);
// Update fallback address list.
fallback_backend_addresses_ = std::move(args.addresses);
if (fallback_backend_addresses_.ok()) {
// Add null LB token attributes.
for (EndpointAddresses& addresses : *fallback_backend_addresses_) {
addresses = EndpointAddresses(
addresses.addresses(),
addresses.args().SetObject(
MakeRefCounted<TokenAndClientStatsArg>("", nullptr)));
}
if (!args.addresses.ok()) {
fallback_backend_addresses_ = args.addresses.status();
} else {
fallback_backend_addresses_ = std::make_shared<NullLbTokenEndpointIterator>(
std::move(*args.addresses));
}
resolution_note_ = std::move(args.resolution_note);
// Update balancer channel.
@ -1569,6 +1614,12 @@ absl::Status GrpcLb::UpdateLocked(UpdateArgs args) {
absl::Status GrpcLb::UpdateBalancerChannelLocked() {
// Get balancer addresses.
EndpointAddressesList balancer_addresses = ExtractBalancerAddresses(args_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
for (const auto& endpoint : balancer_addresses) {
gpr_log(GPR_INFO, "[grpclb %p] balancer address: %s", this,
endpoint.ToString().c_str());
}
}
absl::Status status;
if (balancer_addresses.empty()) {
status = absl::UnavailableError("balancer address list must be non-empty");
@ -1747,6 +1798,12 @@ OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
return lb_policy;
}
bool EndpointIteratorIsEmpty(const EndpointAddressesIterator& endpoints) {
bool empty = true;
endpoints.ForEach([&](const EndpointAddresses&) { empty = false; });
return empty;
}
void GrpcLb::CreateOrUpdateChildPolicyLocked() {
if (shutting_down_) return;
// Construct update args.
@ -1760,16 +1817,17 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() {
// picks.
update_args.addresses = fallback_backend_addresses_;
if (fallback_backend_addresses_.ok() &&
fallback_backend_addresses_->empty()) {
EndpointIteratorIsEmpty(**fallback_backend_addresses_)) {
update_args.resolution_note = absl::StrCat(
"grpclb in fallback mode without any balancer addresses: ",
"grpclb in fallback mode without any fallback addresses: ",
resolution_note_);
}
} else {
update_args.addresses = serverlist_->GetServerAddressList(
lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats());
is_backend_from_grpclb_load_balancer = true;
if (update_args.addresses.ok() && update_args.addresses->empty()) {
if (update_args.addresses.ok() &&
EndpointIteratorIsEmpty(**update_args.addresses)) {
update_args.resolution_note = "empty serverlist from grpclb balancer";
}
}

@ -661,7 +661,7 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) {
if (args.addresses.ok()) {
std::set<EndpointAddressSet> current_endpoints;
std::set<grpc_resolved_address, ResolvedAddressLessThan> current_addresses;
for (const EndpointAddresses& endpoint : *args.addresses) {
(*args.addresses)->ForEach([&](const EndpointAddresses& endpoint) {
EndpointAddressSet key(endpoint.addresses());
current_endpoints.emplace(key);
for (const grpc_resolved_address& address : endpoint.addresses()) {
@ -708,7 +708,7 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) {
}
it->second->DisableEjection();
}
}
});
// Remove any entries we no longer need in the subchannel map.
for (auto it = subchannel_state_map_.begin();
it != subchannel_state_map_.end();) {
@ -753,7 +753,6 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) {
update_args.addresses = std::move(args.addresses);
update_args.resolution_note = std::move(args.resolution_note);
update_args.config = config_->child_policy();
// Update the policy.
update_args.args = std::move(args.args);
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
gpr_log(GPR_INFO,

@ -21,7 +21,6 @@
#include <inttypes.h>
#include <string.h>
#include <algorithm>
#include <memory>
#include <set>
#include <string>
@ -114,7 +113,7 @@ class PickFirst : public LoadBalancingPolicy {
public:
class SubchannelData {
public:
SubchannelData(SubchannelList* subchannel_list,
SubchannelData(SubchannelList* subchannel_list, size_t index,
RefCountedPtr<SubchannelInterface> subchannel);
SubchannelInterface* subchannel() const { return subchannel_.get(); }
@ -125,12 +124,6 @@ class PickFirst : public LoadBalancingPolicy {
return connectivity_status_;
}
// Returns the index into the subchannel list of this object.
size_t Index() const {
return static_cast<size_t>(this -
&subchannel_list_->subchannels_.front());
}
// Resets the connection backoff.
void ResetBackoffLocked() {
if (subchannel_ != nullptr) subchannel_->ResetBackoff();
@ -153,10 +146,8 @@ class PickFirst : public LoadBalancingPolicy {
class Watcher
: public SubchannelInterface::ConnectivityStateWatcherInterface {
public:
Watcher(SubchannelData* subchannel_data,
RefCountedPtr<SubchannelList> subchannel_list)
: subchannel_data_(subchannel_data),
subchannel_list_(std::move(subchannel_list)) {}
Watcher(RefCountedPtr<SubchannelList> subchannel_list, size_t index)
: subchannel_list_(std::move(subchannel_list)), index_(index) {}
~Watcher() override {
subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor");
@ -164,8 +155,8 @@ class PickFirst : public LoadBalancingPolicy {
void OnConnectivityStateChange(grpc_connectivity_state new_state,
absl::Status status) override {
subchannel_data_->OnConnectivityStateChange(new_state,
std::move(status));
subchannel_list_->subchannels_[index_].OnConnectivityStateChange(
new_state, std::move(status));
}
grpc_pollset_set* interested_parties() override {
@ -173,8 +164,8 @@ class PickFirst : public LoadBalancingPolicy {
}
private:
SubchannelData* subchannel_data_;
RefCountedPtr<SubchannelList> subchannel_list_;
const size_t index_;
};
// This method will be invoked once soon after instantiation to report
@ -193,6 +184,7 @@ class PickFirst : public LoadBalancingPolicy {
// Backpointer to owning subchannel list. Not owned.
SubchannelList* subchannel_list_;
const size_t index_;
// The subchannel.
RefCountedPtr<SubchannelInterface> subchannel_;
// Will be non-null when the subchannel's state is being watched.
@ -205,7 +197,8 @@ class PickFirst : public LoadBalancingPolicy {
};
SubchannelList(RefCountedPtr<PickFirst> policy,
EndpointAddressesList addresses, const ChannelArgs& args);
EndpointAddressesIterator* addresses,
const ChannelArgs& args);
~SubchannelList() override;
@ -321,6 +314,14 @@ class PickFirst : public LoadBalancingPolicy {
void UnsetSelectedSubchannel();
// When ExitIdleLocked() is called, we create a subchannel_list_ and start
// trying to connect, but we don't actually change state_ until the first
// subchannel reports CONNECTING. So in order to know if we're really
// idle, we need to check both state_ and subchannel_list_.
bool IsIdle() const {
return state_ == GRPC_CHANNEL_IDLE && subchannel_list_ == nullptr;
}
// Whether we should enable health watching.
const bool enable_health_watch_;
// Whether we should omit our status message prefix.
@ -388,10 +389,7 @@ void PickFirst::ShutdownLocked() {
void PickFirst::ExitIdleLocked() {
if (shutdown_) return;
// Need to check subchannel_list_ being null here, in case the
// application calls channel->GetState(true) again before we
// transition to state CONNECTING.
if (state_ == GRPC_CHANNEL_IDLE && subchannel_list_ == nullptr) {
if (IsIdle()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO, "Pick First %p exiting idle", this);
}
@ -408,9 +406,9 @@ void PickFirst::ResetBackoffLocked() {
void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() {
// Create a subchannel list from latest_update_args_.
EndpointAddressesList addresses;
EndpointAddressesIterator* addresses = nullptr;
if (latest_update_args_.addresses.ok()) {
addresses = *latest_update_args_.addresses;
addresses = latest_update_args_.addresses->get();
}
// Replace latest_pending_subchannel_list_.
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace) &&
@ -420,7 +418,7 @@ void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() {
latest_pending_subchannel_list_.get());
}
latest_pending_subchannel_list_ = MakeOrphanable<SubchannelList>(
Ref(), std::move(addresses), latest_update_args_.args);
Ref(), addresses, latest_update_args_.args);
// Empty update or no valid subchannels. Put the channel in
// TRANSIENT_FAILURE and request re-resolution.
if (latest_pending_subchannel_list_->size() == 0) {
@ -478,9 +476,7 @@ class AddressFamilyIterator {
absl::Status PickFirst::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
if (args.addresses.ok()) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
args.addresses->size());
gpr_log(GPR_INFO, "Pick First %p received update", this);
} else {
gpr_log(GPR_INFO, "Pick First %p received update with address error: %s",
this, args.addresses.status().ToString().c_str());
@ -490,13 +486,18 @@ absl::Status PickFirst::UpdateLocked(UpdateArgs args) {
absl::Status status;
if (!args.addresses.ok()) {
status = args.addresses.status();
} else if (args.addresses->empty()) {
} else {
EndpointAddressesList endpoints;
(*args.addresses)->ForEach([&](const EndpointAddresses& endpoint) {
endpoints.push_back(endpoint);
});
if (endpoints.empty()) {
status = absl::UnavailableError("address list must not be empty");
} else {
// Shuffle the list if needed.
auto config = static_cast<PickFirstConfig*>(args.config.get());
if (config->shuffle_addresses()) {
absl::c_shuffle(*args.addresses, bit_gen_);
absl::c_shuffle(endpoints, bit_gen_);
}
// Flatten the list so that we have one address per endpoint.
// While we're iterating, also determine the desired address family
@ -504,19 +505,21 @@ absl::Status PickFirst::UpdateLocked(UpdateArgs args) {
// the interleaving below.
std::set<absl::string_view> address_families;
std::vector<AddressFamilyIterator> address_family_order;
EndpointAddressesList endpoints;
for (const auto& endpoint : *args.addresses) {
EndpointAddressesList flattened_endpoints;
for (const auto& endpoint : endpoints) {
for (const auto& address : endpoint.addresses()) {
endpoints.emplace_back(address, endpoint.args());
flattened_endpoints.emplace_back(address, endpoint.args());
if (IsPickFirstHappyEyeballsEnabled()) {
absl::string_view scheme = GetAddressFamily(address);
bool inserted = address_families.insert(scheme).second;
if (inserted) {
address_family_order.emplace_back(scheme, endpoints.size() - 1);
address_family_order.emplace_back(scheme,
flattened_endpoints.size() - 1);
}
}
}
}
endpoints = std::move(flattened_endpoints);
// Interleave addresses as per RFC-8305 section 4.
if (IsPickFirstHappyEyeballsEnabled()) {
EndpointAddressesList interleaved_endpoints;
@ -532,9 +535,10 @@ absl::Status PickFirst::UpdateLocked(UpdateArgs args) {
} while (endpoint == nullptr);
interleaved_endpoints.emplace_back(std::move(*endpoint));
}
args.addresses = std::move(interleaved_endpoints);
} else {
args.addresses = std::move(endpoints);
endpoints = std::move(interleaved_endpoints);
}
args.addresses =
std::make_shared<EndpointAddressesListIterator>(std::move(endpoints));
}
}
// If the update contains a resolver error and we have a previous update
@ -546,7 +550,7 @@ absl::Status PickFirst::UpdateLocked(UpdateArgs args) {
latest_update_args_ = std::move(args);
// If we are not in idle, start connection attempt immediately.
// Otherwise, we defer the attempt into ExitIdleLocked().
if (state_ != GRPC_CHANNEL_IDLE) {
if (!IsIdle()) {
AttemptToConnectUsingLatestUpdateArgsLocked();
}
return status;
@ -612,18 +616,20 @@ void PickFirst::HealthWatcher::OnConnectivityStateChange(
//
PickFirst::SubchannelList::SubchannelData::SubchannelData(
SubchannelList* subchannel_list,
SubchannelList* subchannel_list, size_t index,
RefCountedPtr<SubchannelInterface> subchannel)
: subchannel_list_(subchannel_list), subchannel_(std::move(subchannel)) {
: subchannel_list_(subchannel_list),
index_(index),
subchannel_(std::move(subchannel)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
"[PF %p] subchannel list %p index %" PRIuPTR
" (subchannel %p): starting watch",
subchannel_list_->policy_.get(), subchannel_list_,
subchannel_list_->size(), subchannel_.get());
subchannel_list_->policy_.get(), subchannel_list_, index_,
subchannel_.get());
}
auto watcher = std::make_unique<Watcher>(
this, subchannel_list_->Ref(DEBUG_LOCATION, "Watcher"));
subchannel_list_->Ref(DEBUG_LOCATION, "Watcher"), index_);
pending_watcher_ = watcher.get();
subchannel_->WatchConnectivityState(std::move(watcher));
}
@ -634,7 +640,7 @@ void PickFirst::SubchannelList::SubchannelData::ShutdownLocked() {
gpr_log(GPR_INFO,
"[PF %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
" (subchannel %p): cancelling watch and unreffing subchannel",
subchannel_list_->policy_.get(), subchannel_list_, Index(),
subchannel_list_->policy_.get(), subchannel_list_, index_,
subchannel_list_->size(), subchannel_.get());
}
subchannel_->CancelConnectivityStateWatch(pending_watcher_);
@ -654,7 +660,7 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange(
"status=%s, shutting_down=%d, pending_watcher=%p, "
"seen_transient_failure=%d, p->selected_=%p, "
"p->subchannel_list_=%p, p->latest_pending_subchannel_list_=%p",
p, subchannel_list_, Index(), subchannel_list_->size(),
p, subchannel_list_, index_, subchannel_list_->size(),
subchannel_.get(),
(connectivity_state_.has_value()
? ConnectivityStateName(*connectivity_state_)
@ -766,7 +772,7 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange(
if (!IsPickFirstHappyEyeballsEnabled()) {
// Ignore any other updates for subchannels we're not currently trying to
// connect to.
if (Index() != subchannel_list_->attempting_index_) return;
if (index_ != subchannel_list_->attempting_index_) return;
// React to the connectivity state.
ReactToConnectivityStateLocked();
return;
@ -779,7 +785,7 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange(
if (!prev_seen_transient_failure && seen_transient_failure_) {
// If a connection attempt fails before the timer fires, then
// cancel the timer and start connecting on the next subchannel.
if (Index() == subchannel_list_->attempting_index_) {
if (index_ == subchannel_list_->attempting_index_) {
if (subchannel_list_->timer_handle_.has_value()) {
p->channel_control_helper()->GetEventEngine()->Cancel(
*subchannel_list_->timer_handle_);
@ -853,7 +859,7 @@ void PickFirst::SubchannelList::SubchannelData::
// We skip subchannels in state TRANSIENT_FAILURE to avoid a
// large recursion that could overflow the stack.
SubchannelData* found_subchannel = nullptr;
for (size_t next_index = Index() + 1;
for (size_t next_index = index_ + 1;
next_index < subchannel_list_->size(); ++next_index) {
SubchannelData* sc = &subchannel_list_->subchannels_[next_index];
GPR_ASSERT(sc->connectivity_state_.has_value());
@ -941,14 +947,14 @@ void PickFirst::SubchannelList::SubchannelData::RequestConnectionWithTimer() {
GPR_ASSERT(connectivity_state_ == GRPC_CHANNEL_CONNECTING);
}
// If this is not the last subchannel in the list, start the timer.
if (Index() != subchannel_list_->size() - 1) {
if (index_ != subchannel_list_->size() - 1) {
PickFirst* p = subchannel_list_->policy_.get();
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
"Pick First %p subchannel list %p: starting Connection "
"Attempt Delay timer for %" PRId64 "ms for index %" PRIuPTR,
p, subchannel_list_, p->connection_attempt_delay_.millis(),
Index());
index_);
}
subchannel_list_->timer_handle_ =
p->channel_control_helper()->GetEventEngine()->RunAfter(
@ -1036,7 +1042,7 @@ void PickFirst::SubchannelList::SubchannelData::ProcessUnselectedReadyLocked() {
}
// Unref all other subchannels in the list.
for (size_t i = 0; i < subchannel_list_->size(); ++i) {
if (i != Index()) {
if (i != index_) {
subchannel_list_->subchannels_[i].ShutdownLocked();
}
}
@ -1047,7 +1053,7 @@ void PickFirst::SubchannelList::SubchannelData::ProcessUnselectedReadyLocked() {
//
PickFirst::SubchannelList::SubchannelList(RefCountedPtr<PickFirst> policy,
EndpointAddressesList addresses,
EndpointAddressesIterator* addresses,
const ChannelArgs& args)
: InternallyRefCounted<SubchannelList>(
GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace) ? "SubchannelList"
@ -1057,14 +1063,12 @@ PickFirst::SubchannelList::SubchannelList(RefCountedPtr<PickFirst> policy,
.Remove(
GRPC_ARG_INTERNAL_PICK_FIRST_OMIT_STATUS_MESSAGE_PREFIX)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
"[PF %p] Creating subchannel list %p for %" PRIuPTR
" subchannels - channel args: %s",
policy_.get(), this, addresses.size(), args_.ToString().c_str());
gpr_log(GPR_INFO, "[PF %p] Creating subchannel list %p - channel args: %s",
policy_.get(), this, args_.ToString().c_str());
}
subchannels_.reserve(addresses.size());
if (addresses == nullptr) return;
// Create a subchannel for each address.
for (const EndpointAddresses& address : addresses) {
addresses->ForEach([&](const EndpointAddresses& address) {
GPR_ASSERT(address.addresses().size() == 1);
RefCountedPtr<SubchannelInterface> subchannel =
policy_->channel_control_helper()->CreateSubchannel(
@ -1076,7 +1080,7 @@ PickFirst::SubchannelList::SubchannelList(RefCountedPtr<PickFirst> policy,
"[PF %p] could not create subchannel for address %s, ignoring",
policy_.get(), address.ToString().c_str());
}
continue;
return;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
@ -1085,8 +1089,8 @@ PickFirst::SubchannelList::SubchannelList(RefCountedPtr<PickFirst> policy,
policy_.get(), this, subchannels_.size(), subchannel.get(),
address.ToString().c_str());
}
subchannels_.emplace_back(this, std::move(subchannel));
}
subchannels_.emplace_back(this, subchannels_.size(), std::move(subchannel));
});
}
PickFirst::SubchannelList::~SubchannelList() {

@ -684,7 +684,8 @@ absl::Status PriorityLb::ChildPriority::UpdateLocked(
if (priority_policy_->addresses_.ok()) {
auto it = priority_policy_->addresses_->find(name_);
if (it == priority_policy_->addresses_->end()) {
update_args.addresses.emplace();
update_args.addresses = std::make_shared<EndpointAddressesListIterator>(
EndpointAddressesList());
} else {
update_args.addresses = it->second;
}

@ -554,7 +554,8 @@ void RingHash::RingHashEndpoint::UpdateChildPolicyLocked() {
GPR_ASSERT(config.ok());
// Update child policy.
LoadBalancingPolicy::UpdateArgs update_args;
update_args.addresses.emplace().emplace_back(ring_hash_->endpoints_[index_]);
update_args.addresses =
std::make_shared<SingleEndpointIterator>(ring_hash_->endpoints_[index_]);
update_args.args = ring_hash_->args_;
update_args.config = std::move(*config);
// TODO(roth): If the child reports a non-OK status with the update,
@ -622,18 +623,14 @@ absl::Status RingHash::UpdateLocked(UpdateArgs args) {
// Check address list.
if (args.addresses.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
gpr_log(GPR_INFO, "[RH %p] received update with %" PRIuPTR " addresses",
this, args.addresses->size());
gpr_log(GPR_INFO, "[RH %p] received update", this);
}
// De-dup endpoints, taking weight into account.
endpoints_.clear();
endpoints_.reserve(args.addresses->size());
std::map<EndpointAddressSet, size_t> endpoint_indices;
size_t num_skipped = 0;
for (size_t i = 0; i < args.addresses->size(); ++i) {
EndpointAddresses& endpoint = (*args.addresses)[i];
(*args.addresses)->ForEach([&](const EndpointAddresses& endpoint) {
const EndpointAddressSet key(endpoint.addresses());
auto p = endpoint_indices.emplace(key, i - num_skipped);
auto p = endpoint_indices.emplace(key, endpoints_.size());
if (!p.second) {
// Duplicate endpoint. Combine weights and skip the dup.
EndpointAddresses& prev_endpoint = endpoints_[p.first->second];
@ -651,11 +648,10 @@ absl::Status RingHash::UpdateLocked(UpdateArgs args) {
prev_endpoint.addresses(),
prev_endpoint.args().Set(GRPC_ARG_ADDRESS_WEIGHT,
weight_arg + prev_weight_arg));
++num_skipped;
} else {
endpoints_.push_back(std::move(endpoint));
}
endpoints_.push_back(endpoint);
}
});
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
gpr_log(GPR_INFO, "[RH %p] received update with addresses error: %s",

@ -707,7 +707,7 @@ class RlsLb : public LoadBalancingPolicy {
OrphanablePtr<RlsChannel> rls_channel_ ABSL_GUARDED_BY(mu_);
// Accessed only from within WorkSerializer.
absl::StatusOr<EndpointAddressesList> addresses_;
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses_;
ChannelArgs channel_args_;
RefCountedPtr<RlsLbConfig> config_;
RefCountedPtr<ChildPolicyWrapper> default_child_policy_;
@ -1858,6 +1858,27 @@ RlsLb::RlsLb(Args args) : LoadBalancingPolicy(std::move(args)), cache_(this) {
}
}
bool EndpointsEqual(
const absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> endpoints1,
const absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>>
endpoints2) {
if (endpoints1.status() != endpoints2.status()) return false;
if (endpoints1.ok()) {
std::vector<EndpointAddresses> e1_list;
(*endpoints1)->ForEach([&](const EndpointAddresses& endpoint) {
e1_list.push_back(endpoint);
});
size_t i = 0;
bool different = false;
(*endpoints2)->ForEach([&](const EndpointAddresses& endpoint) {
if (endpoint != e1_list[i++]) different = true;
});
if (different) return false;
if (i != e1_list.size()) return false;
}
return true;
}
absl::Status RlsLb::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_rls_trace)) {
gpr_log(GPR_INFO, "[rlslb %p] policy updated", this);
@ -1875,7 +1896,7 @@ absl::Status RlsLb::UpdateLocked(UpdateArgs args) {
// Swap out addresses.
// If the new address list is an error and we have an existing address list,
// stick with the existing addresses.
absl::StatusOr<EndpointAddressesList> old_addresses;
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> old_addresses;
if (args.addresses.ok()) {
old_addresses = std::move(addresses_);
addresses_ = std::move(args.addresses);
@ -1888,7 +1909,7 @@ absl::Status RlsLb::UpdateLocked(UpdateArgs args) {
bool update_child_policies =
old_config == nullptr ||
old_config->child_policy_config() != config_->child_policy_config() ||
old_addresses != addresses_ || args.args != channel_args_;
!EndpointsEqual(old_addresses, addresses_) || args.args != channel_args_;
// If default target changes, swap out child policy.
bool created_default_child = false;
if (old_config == nullptr ||

@ -125,14 +125,14 @@ class OldRoundRobin : public LoadBalancingPolicy {
: public SubchannelList<RoundRobinSubchannelList,
RoundRobinSubchannelData> {
public:
RoundRobinSubchannelList(OldRoundRobin* policy, ServerAddressList addresses,
RoundRobinSubchannelList(OldRoundRobin* policy,
EndpointAddressesIterator* addresses,
const ChannelArgs& args)
: SubchannelList(policy,
(GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)
? "RoundRobinSubchannelList"
: nullptr),
std::move(addresses), policy->channel_control_helper(),
args) {
addresses, policy->channel_control_helper(), args) {
// Need to maintain a ref to the LB policy as long as we maintain
// any references to subchannels, since the subchannels'
// pollset_sets will include the LB policy's pollset_set.
@ -277,13 +277,12 @@ void OldRoundRobin::ResetBackoffLocked() {
}
absl::Status OldRoundRobin::UpdateLocked(UpdateArgs args) {
ServerAddressList addresses;
EndpointAddressesIterator* addresses = nullptr;
if (args.addresses.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
this, args.addresses->size());
gpr_log(GPR_INFO, "[RR %p] received update", this);
}
addresses = std::move(*args.addresses);
addresses = args.addresses->get();
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
gpr_log(GPR_INFO, "[RR %p] received update with address error: %s", this,
@ -299,8 +298,8 @@ absl::Status OldRoundRobin::UpdateLocked(UpdateArgs args) {
gpr_log(GPR_INFO, "[RR %p] replacing previous pending subchannel list %p",
this, latest_pending_subchannel_list_.get());
}
latest_pending_subchannel_list_ = MakeRefCounted<RoundRobinSubchannelList>(
this, std::move(addresses), args.args);
latest_pending_subchannel_list_ =
MakeRefCounted<RoundRobinSubchannelList>(this, addresses, args.args);
latest_pending_subchannel_list_->StartWatchingLocked(args.args);
// If the new list is empty, immediately promote it to
// subchannel_list_ and report TRANSIENT_FAILURE.
@ -524,7 +523,7 @@ class RoundRobin : public LoadBalancingPolicy {
class RoundRobinEndpointList : public EndpointList {
public:
RoundRobinEndpointList(RefCountedPtr<RoundRobin> round_robin,
const EndpointAddressesList& endpoints,
EndpointAddressesIterator* endpoints,
const ChannelArgs& args)
: EndpointList(std::move(round_robin),
GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)
@ -687,13 +686,12 @@ void RoundRobin::ResetBackoffLocked() {
}
absl::Status RoundRobin::UpdateLocked(UpdateArgs args) {
EndpointAddressesList addresses;
EndpointAddressesIterator* addresses = nullptr;
if (args.addresses.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " endpoints",
this, args.addresses->size());
gpr_log(GPR_INFO, "[RR %p] received update", this);
}
addresses = std::move(*args.addresses);
addresses = args.addresses->get();
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
gpr_log(GPR_INFO, "[RR %p] received update with address error: %s", this,
@ -710,8 +708,7 @@ absl::Status RoundRobin::UpdateLocked(UpdateArgs args) {
latest_pending_endpoint_list_.get());
}
latest_pending_endpoint_list_ = MakeOrphanable<RoundRobinEndpointList>(
Ref(DEBUG_LOCATION, "RoundRobinEndpointList"), std::move(addresses),
args.args);
Ref(DEBUG_LOCATION, "RoundRobinEndpointList"), addresses, args.args);
// If the new list is empty, immediately promote it to
// endpoint_list_ and report TRANSIENT_FAILURE.
if (latest_pending_endpoint_list_->size() == 0) {

@ -42,6 +42,7 @@
#include "src/core/lib/iomgr/iomgr_fwd.h"
#include "src/core/lib/load_balancing/lb_policy.h"
#include "src/core/lib/load_balancing/subchannel_interface.h"
#include "src/core/lib/resolver/endpoint_addresses.h"
#include "src/core/lib/resolver/server_address.h"
#include "src/core/lib/transport/connectivity_state.h"
@ -208,7 +209,7 @@ class SubchannelList : public DualRefCounted<SubchannelListType> {
protected:
SubchannelList(LoadBalancingPolicy* policy, const char* tracer,
ServerAddressList addresses,
EndpointAddressesIterator* addresses,
LoadBalancingPolicy::ChannelControlHelper* helper,
const ChannelArgs& args);
@ -365,19 +366,18 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::ShutdownLocked() {
template <typename SubchannelListType, typename SubchannelDataType>
SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
LoadBalancingPolicy* policy, const char* tracer,
ServerAddressList addresses,
EndpointAddressesIterator* addresses,
LoadBalancingPolicy::ChannelControlHelper* helper, const ChannelArgs& args)
: DualRefCounted<SubchannelListType>(tracer),
policy_(policy),
tracer_(tracer) {
if (GPR_UNLIKELY(tracer_ != nullptr)) {
gpr_log(GPR_INFO,
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
tracer_, policy, this, addresses.size());
gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p", tracer_, policy,
this);
}
subchannels_.reserve(addresses.size());
if (addresses == nullptr) return;
// Create a subchannel for each address.
for (ServerAddress address : addresses) {
addresses->ForEach([&](const EndpointAddresses& address) {
RefCountedPtr<SubchannelInterface> subchannel =
helper->CreateSubchannel(address.address(), address.args(), args);
if (subchannel == nullptr) {
@ -387,7 +387,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
"[%s %p] could not create subchannel for address %s, ignoring",
tracer_, policy_, address.ToString().c_str());
}
continue;
return;
}
if (GPR_UNLIKELY(tracer_ != nullptr)) {
gpr_log(GPR_INFO,
@ -397,8 +397,8 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
address.ToString().c_str());
}
subchannels_.emplace_back();
subchannels_.back().Init(this, std::move(address), std::move(subchannel));
}
subchannels_.back().Init(this, address, std::move(subchannel));
});
}
template <typename SubchannelListType, typename SubchannelDataType>

@ -247,14 +247,13 @@ class OldWeightedRoundRobin : public LoadBalancingPolicy {
WeightedRoundRobinSubchannelData> {
public:
WeightedRoundRobinSubchannelList(OldWeightedRoundRobin* policy,
ServerAddressList addresses,
EndpointAddressesIterator* addresses,
const ChannelArgs& args)
: SubchannelList(policy,
(GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)
? "WeightedRoundRobinSubchannelList"
: nullptr),
std::move(addresses), policy->channel_control_helper(),
args) {
addresses, policy->channel_control_helper(), args) {
// Need to maintain a ref to the LB policy as long as we maintain
// any references to subchannels, since the subchannels'
// pollset_sets will include the LB policy's pollset_set.
@ -675,11 +674,10 @@ void OldWeightedRoundRobin::ResetBackoffLocked() {
absl::Status OldWeightedRoundRobin::UpdateLocked(UpdateArgs args) {
global_stats().IncrementWrrUpdates();
config_ = std::move(args.config);
ServerAddressList addresses;
std::shared_ptr<EndpointAddressesIterator> addresses;
if (args.addresses.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)) {
gpr_log(GPR_INFO, "[WRR %p] received update with %" PRIuPTR " addresses",
this, args.addresses->size());
gpr_log(GPR_INFO, "[WRR %p] received update", this);
}
// Weed out duplicate addresses. Also sort the addresses so that if
// the set of the addresses don't change, their indexes in the
@ -698,10 +696,12 @@ absl::Status OldWeightedRoundRobin::UpdateLocked(UpdateArgs args) {
return memcmp(addr1.addr, addr2.addr, addr1.len) < 0;
}
};
std::set<ServerAddress, AddressLessThan> ordered_addresses(
args.addresses->begin(), args.addresses->end());
addresses =
ServerAddressList(ordered_addresses.begin(), ordered_addresses.end());
std::set<ServerAddress, AddressLessThan> ordered_addresses;
(*args.addresses)->ForEach([&](const EndpointAddresses& endpoint) {
ordered_addresses.insert(endpoint);
});
addresses = std::make_shared<EndpointAddressesListIterator>(
ServerAddressList(ordered_addresses.begin(), ordered_addresses.end()));
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)) {
gpr_log(GPR_INFO, "[WRR %p] received update with address error: %s", this,
@ -718,8 +718,8 @@ absl::Status OldWeightedRoundRobin::UpdateLocked(UpdateArgs args) {
this, latest_pending_subchannel_list_.get());
}
latest_pending_subchannel_list_ =
MakeRefCounted<WeightedRoundRobinSubchannelList>(
this, std::move(addresses), args.args);
MakeRefCounted<WeightedRoundRobinSubchannelList>(this, addresses.get(),
args.args);
latest_pending_subchannel_list_->StartWatchingLocked(args.args);
// If the new list is empty, immediately promote it to
// subchannel_list_ and report TRANSIENT_FAILURE.
@ -1079,7 +1079,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy {
};
WrrEndpointList(RefCountedPtr<WeightedRoundRobin> wrr,
const EndpointAddressesList& endpoints,
EndpointAddressesIterator* endpoints,
const ChannelArgs& args)
: EndpointList(std::move(wrr),
GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)
@ -1516,11 +1516,10 @@ void WeightedRoundRobin::ResetBackoffLocked() {
absl::Status WeightedRoundRobin::UpdateLocked(UpdateArgs args) {
global_stats().IncrementWrrUpdates();
config_ = std::move(args.config);
EndpointAddressesList addresses;
std::shared_ptr<EndpointAddressesIterator> addresses;
if (args.addresses.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)) {
gpr_log(GPR_INFO, "[WRR %p] received update with %" PRIuPTR " addresses",
this, args.addresses->size());
gpr_log(GPR_INFO, "[WRR %p] received update", this);
}
// Weed out duplicate endpoints. Also sort the endpoints so that if
// the set of endpoints doesn't change, their indexes in the endpoint
@ -1539,10 +1538,13 @@ absl::Status WeightedRoundRobin::UpdateLocked(UpdateArgs args) {
return e1 < e2;
}
};
std::set<EndpointAddresses, EndpointAddressesLessThan> ordered_addresses(
args.addresses->begin(), args.addresses->end());
addresses = EndpointAddressesList(ordered_addresses.begin(),
ordered_addresses.end());
std::set<EndpointAddresses, EndpointAddressesLessThan> ordered_addresses;
(*args.addresses)->ForEach([&](const EndpointAddresses& endpoint) {
ordered_addresses.insert(endpoint);
});
addresses =
std::make_shared<EndpointAddressesListIterator>(EndpointAddressesList(
ordered_addresses.begin(), ordered_addresses.end()));
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)) {
gpr_log(GPR_INFO, "[WRR %p] received update with address error: %s", this,
@ -1559,7 +1561,7 @@ absl::Status WeightedRoundRobin::UpdateLocked(UpdateArgs args) {
this, latest_pending_endpoint_list_.get());
}
latest_pending_endpoint_list_ =
MakeOrphanable<WrrEndpointList>(Ref(), std::move(addresses), args.args);
MakeOrphanable<WrrEndpointList>(Ref(), addresses.get(), args.args);
// If the new list is empty, immediately promote it to
// endpoint_list_ and report TRANSIENT_FAILURE.
if (latest_pending_endpoint_list_->size() == 0) {

@ -157,10 +157,10 @@ class WeightedTargetLb : public LoadBalancingPolicy {
void Orphan() override;
absl::Status UpdateLocked(const WeightedTargetLbConfig::ChildConfig& config,
absl::StatusOr<EndpointAddressesList> addresses,
const std::string& resolution_note,
const ChannelArgs& args);
absl::Status UpdateLocked(
const WeightedTargetLbConfig::ChildConfig& config,
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses,
const std::string& resolution_note, const ChannelArgs& args);
void ResetBackoffLocked();
void DeactivateLocked();
@ -338,11 +338,12 @@ absl::Status WeightedTargetLb::UpdateLocked(UpdateArgs args) {
target = MakeOrphanable<WeightedChild>(
Ref(DEBUG_LOCATION, "WeightedChild"), name);
}
absl::StatusOr<EndpointAddressesList> addresses;
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses;
if (address_map.ok()) {
auto it = address_map->find(name);
if (it == address_map->end()) {
addresses.emplace();
addresses = std::make_shared<EndpointAddressesListIterator>(
EndpointAddressesList());
} else {
addresses = std::move(it->second);
}
@ -589,7 +590,7 @@ WeightedTargetLb::WeightedChild::CreateChildPolicyLocked(
absl::Status WeightedTargetLb::WeightedChild::UpdateLocked(
const WeightedTargetLbConfig::ChildConfig& config,
absl::StatusOr<EndpointAddressesList> addresses,
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses,
const std::string& resolution_note, const ChannelArgs& args) {
if (weighted_target_policy_->shutting_down_) return absl::OkStatus();
// Update child weight.

@ -199,8 +199,21 @@ class CdsLb : public LoadBalancingPolicy {
// The root of the tree is config_->cluster().
std::map<std::string, WatcherState> watchers_;
// TODO(roth, yashkt): These are here because XdsCertificateProvider
// does not store the actual underlying cert providers, it stores only
// their distributors, so we need to hold a ref to the cert providers
// here. However, in the aggregate cluster case, there may be multiple
// clusters in the same cert provider, and we're only tracking the cert
// providers for the most recent underlying cluster here. This is
// clearly a bug, and I think it will cause us to stop getting updates
// for all but one of the cert providers in the aggregate cluster
// case. Need to figure out the right way to fix this -- I don't
// think we want to store another map here, so ideally, we should just
// have XdsCertificateProvider actually hold the refs to the cert
// providers instead of just the distributors.
RefCountedPtr<grpc_tls_certificate_provider> root_certificate_provider_;
RefCountedPtr<grpc_tls_certificate_provider> identity_certificate_provider_;
RefCountedPtr<XdsCertificateProvider> xds_certificate_provider_;
// Child LB policy.
@ -594,20 +607,7 @@ absl::Status CdsLb::UpdateXdsCertificateProvider(
root_provider_instance_name, "\" not recognized."));
}
}
if (root_certificate_provider_ != new_root_provider) {
if (root_certificate_provider_ != nullptr &&
root_certificate_provider_->interested_parties() != nullptr) {
grpc_pollset_set_del_pollset_set(
interested_parties(),
root_certificate_provider_->interested_parties());
}
if (new_root_provider != nullptr &&
new_root_provider->interested_parties() != nullptr) {
grpc_pollset_set_add_pollset_set(interested_parties(),
new_root_provider->interested_parties());
}
root_certificate_provider_ = std::move(new_root_provider);
}
xds_certificate_provider_->UpdateRootCertNameAndDistributor(
cluster_name, root_provider_cert_name,
root_certificate_provider_ == nullptr
@ -631,20 +631,7 @@ absl::Status CdsLb::UpdateXdsCertificateProvider(
identity_provider_instance_name, "\" not recognized."));
}
}
if (identity_certificate_provider_ != new_identity_provider) {
if (identity_certificate_provider_ != nullptr &&
identity_certificate_provider_->interested_parties() != nullptr) {
grpc_pollset_set_del_pollset_set(
interested_parties(),
identity_certificate_provider_->interested_parties());
}
if (new_identity_provider != nullptr &&
new_identity_provider->interested_parties() != nullptr) {
grpc_pollset_set_add_pollset_set(
interested_parties(), new_identity_provider->interested_parties());
}
identity_certificate_provider_ = std::move(new_identity_provider);
}
xds_certificate_provider_->UpdateIdentityCertNameAndDistributor(
cluster_name, identity_provider_cert_name,
identity_certificate_provider_ == nullptr

@ -250,7 +250,7 @@ class XdsClusterImplLb : public LoadBalancingPolicy {
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const ChannelArgs& args);
absl::Status UpdateChildPolicyLocked(
absl::StatusOr<EndpointAddressesList> addresses,
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses,
std::string resolution_note, const ChannelArgs& args);
void MaybeUpdatePickerLocked();
@ -569,7 +569,7 @@ OrphanablePtr<LoadBalancingPolicy> XdsClusterImplLb::CreateChildPolicyLocked(
}
absl::Status XdsClusterImplLb::UpdateChildPolicyLocked(
absl::StatusOr<EndpointAddressesList> addresses,
absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses,
std::string resolution_note, const ChannelArgs& args) {
// Create policy if needed.
if (child_policy_ == nullptr) {

@ -149,7 +149,8 @@ class XdsClusterManagerLb : public LoadBalancingPolicy {
absl::Status UpdateLocked(
RefCountedPtr<LoadBalancingPolicy::Config> config,
const absl::StatusOr<EndpointAddressesList>& addresses,
const absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>>&
addresses,
const ChannelArgs& args);
void ExitIdleLocked();
void ResetBackoffLocked();
@ -482,7 +483,7 @@ XdsClusterManagerLb::ClusterChild::CreateChildPolicyLocked(
absl::Status XdsClusterManagerLb::ClusterChild::UpdateLocked(
RefCountedPtr<LoadBalancingPolicy::Config> config,
const absl::StatusOr<EndpointAddressesList>& addresses,
const absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>>& addresses,
const ChannelArgs& args) {
if (xds_cluster_manager_policy_->shutting_down_) return absl::OkStatus();
// Update child weight.

@ -28,6 +28,7 @@
#include <utility>
#include <vector>
#include "absl/functional/function_ref.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
@ -61,6 +62,7 @@
#include "src/core/lib/gprpp/validation_errors.h"
#include "src/core/lib/gprpp/work_serializer.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resolved_address.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/json/json_args.h"
#include "src/core/lib/json/json_object_loader.h"
@ -390,7 +392,7 @@ class XdsClusterResolverLb : public LoadBalancingPolicy {
absl::Status UpdateChildPolicyLocked();
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const ChannelArgs& args);
EndpointAddressesList CreateChildPolicyAddressesLocked();
std::shared_ptr<EndpointAddressesIterator> CreateChildPolicyAddressesLocked();
std::string CreateChildPolicyResolutionNoteLocked();
RefCountedPtr<Config> CreateChildPolicyConfigLocked();
ChannelArgs CreateChildPolicyArgsLocked(const ChannelArgs& args_in);
@ -529,10 +531,16 @@ XdsClusterResolverLb::DiscoveryMechanismEntry::config() const {
->config_->discovery_mechanisms()[discovery_mechanism->index()];
}
std::string MakeChildPolicyName(absl::string_view cluster_name,
size_t child_number) {
return absl::StrCat("{cluster=", cluster_name,
", child_number=", child_number, "}");
}
std::string XdsClusterResolverLb::DiscoveryMechanismEntry::GetChildPolicyName(
size_t priority) const {
return absl::StrCat("{cluster=", config().cluster_name,
", child_number=", priority_child_numbers[priority], "}");
return MakeChildPolicyName(config().cluster_name,
priority_child_numbers[priority]);
}
//
@ -768,15 +776,37 @@ void XdsClusterResolverLb::OnResourceDoesNotExist(size_t index,
// child policy-related methods
//
EndpointAddressesList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
EndpointAddressesList addresses;
for (const auto& discovery_entry : discovery_mechanisms_) {
const auto& priority_list =
GetUpdatePriorityList(*discovery_entry.latest_update);
class PriorityEndpointIterator : public EndpointAddressesIterator {
public:
struct DiscoveryMechanismResult {
std::shared_ptr<const XdsEndpointResource> update;
std::string cluster_name;
std::vector<size_t /*child_number*/> priority_child_numbers;
DiscoveryMechanismResult(
std::shared_ptr<const XdsEndpointResource> resource,
std::string cluster, std::vector<size_t> child_numbers)
: update(std::move(resource)),
cluster_name(std::move(cluster)),
priority_child_numbers(std::move(child_numbers)) {}
std::string GetChildPolicyName(size_t priority) const {
return MakeChildPolicyName(cluster_name,
priority_child_numbers[priority]);
}
};
explicit PriorityEndpointIterator(
std::vector<DiscoveryMechanismResult> results)
: results_(std::move(results)) {}
void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
const override {
for (const auto& entry : results_) {
const auto& priority_list = GetUpdatePriorityList(*entry.update);
for (size_t priority = 0; priority < priority_list.size(); ++priority) {
const auto& priority_entry = priority_list[priority];
std::string priority_child_name =
discovery_entry.GetChildPolicyName(priority);
std::string priority_child_name = entry.GetChildPolicyName(priority);
for (const auto& p : priority_entry.localities) {
const auto& locality_name = p.first;
const auto& locality = p.second;
@ -789,18 +819,33 @@ EndpointAddressesList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
uint32_t endpoint_weight =
locality.lb_weight *
endpoint.args().GetInt(GRPC_ARG_ADDRESS_WEIGHT).value_or(1);
addresses.emplace_back(
callback(EndpointAddresses(
endpoint.addresses(),
endpoint.args()
.SetObject(hierarchical_path_attr)
.Set(GRPC_ARG_ADDRESS_WEIGHT, endpoint_weight)
.SetObject(locality_name->Ref())
.Set(GRPC_ARG_XDS_LOCALITY_WEIGHT, locality.lb_weight));
.Set(GRPC_ARG_XDS_LOCALITY_WEIGHT, locality.lb_weight)));
}
}
}
}
}
private:
std::vector<DiscoveryMechanismResult> results_;
};
std::shared_ptr<EndpointAddressesIterator>
XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
std::vector<PriorityEndpointIterator::DiscoveryMechanismResult> entries;
entries.reserve(discovery_mechanisms_.size());
for (const auto& discovery_entry : discovery_mechanisms_) {
entries.emplace_back(discovery_entry.latest_update,
discovery_entry.config().cluster_name,
discovery_entry.priority_child_numbers);
}
return addresses;
return std::make_shared<PriorityEndpointIterator>(std::move(entries));
}
std::string XdsClusterResolverLb::CreateChildPolicyResolutionNoteLocked() {

@ -18,7 +18,6 @@
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h"
#include <inttypes.h>
#include <stddef.h>
#include <algorithm>
@ -34,6 +33,7 @@
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/functional/function_ref.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
@ -300,8 +300,7 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
void MaybeUpdatePickerLocked();
absl::StatusOr<EndpointAddressesList> UpdateAddressMap(
absl::StatusOr<EndpointAddressesList> endpoints);
void UpdateAddressMap(const EndpointAddressesIterator& endpoints);
RefCountedPtr<SubchannelWrapper> AdoptSubchannel(
const grpc_resolved_address& address,
@ -508,12 +507,36 @@ void XdsOverrideHostLb::ResetBackoffLocked() {
if (child_policy_ != nullptr) child_policy_->ResetBackoffLocked();
}
absl::Status XdsOverrideHostLb::UpdateLocked(UpdateArgs args) {
// Wraps the endpoint iterator and filters out endpoints in state DRAINING.
class ChildEndpointIterator : public EndpointAddressesIterator {
public:
explicit ChildEndpointIterator(
std::shared_ptr<EndpointAddressesIterator> parent_it)
: parent_it_(std::move(parent_it)) {}
void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
const override {
parent_it_->ForEach([&](const EndpointAddresses& endpoint) {
XdsHealthStatus status = GetEndpointHealthStatus(endpoint);
if (status.status() != XdsHealthStatus::kDraining) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
gpr_log(GPR_INFO,
"[xds_override_host_lb %p] Received update with %" PRIuPTR
" addresses",
this, args.addresses.ok() ? args.addresses->size() : 0);
"[xds_override_host_lb %p] endpoint %s: not draining, "
"passing to child",
this, endpoint.ToString().c_str());
}
callback(endpoint);
}
});
}
private:
std::shared_ptr<EndpointAddressesIterator> parent_it_;
};
absl::Status XdsOverrideHostLb::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
gpr_log(GPR_INFO, "[xds_override_host_lb %p] Received update", this);
}
auto old_config = std::move(config_);
// Update config.
@ -521,13 +544,24 @@ absl::Status XdsOverrideHostLb::UpdateLocked(UpdateArgs args) {
if (config_ == nullptr) {
return absl::InvalidArgumentError("Missing policy config");
}
// Update address map and wrap endpoint iterator for child policy.
if (args.addresses.ok()) {
UpdateAddressMap(**args.addresses);
args.addresses =
std::make_shared<ChildEndpointIterator>(std::move(*args.addresses));
} else {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
gpr_log(GPR_INFO, "[xds_override_host_lb %p] address error: %s", this,
args.addresses.status().ToString().c_str());
}
}
// Create child policy if needed.
if (child_policy_ == nullptr) {
child_policy_ = CreateChildPolicyLocked(args.args);
}
// Update child policy.
UpdateArgs update_args;
update_args.addresses = UpdateAddressMap(std::move(args.addresses));
update_args.addresses = std::move(args.addresses);
update_args.resolution_note = std::move(args.resolution_note);
update_args.config = config_->child_config();
update_args.args = std::move(args.args);
@ -578,18 +612,9 @@ OrphanablePtr<LoadBalancingPolicy> XdsOverrideHostLb::CreateChildPolicyLocked(
return lb_policy;
}
absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
absl::StatusOr<EndpointAddressesList> endpoints) {
if (!endpoints.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
gpr_log(GPR_INFO, "[xds_override_host_lb %p] address error: %s", this,
endpoints.status().ToString().c_str());
}
return endpoints;
}
// Construct the list of addresses to pass to the child policy and a
// map of address info from which to update subchannel_map_.
EndpointAddressesList child_addresses;
void XdsOverrideHostLb::UpdateAddressMap(
const EndpointAddressesIterator& endpoints) {
// Construct a map of address info from which to update subchannel_map_.
struct AddressInfo {
XdsHealthStatus eds_health_status;
RefCountedStringValue address_list;
@ -597,25 +622,18 @@ absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
: eds_health_status(status), address_list(std::move(addresses)) {}
};
std::map<const std::string, AddressInfo> addresses_for_map;
for (const auto& endpoint : *endpoints) {
endpoints.ForEach([&](const EndpointAddresses& endpoint) {
XdsHealthStatus status = GetEndpointHealthStatus(endpoint);
if (status.status() != XdsHealthStatus::kDraining) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
gpr_log(GPR_INFO,
"[xds_override_host_lb %p] endpoint %s: not draining, "
"passing to child",
this, endpoint.ToString().c_str());
}
child_addresses.push_back(endpoint);
} else if (!config_->override_host_status_set().Contains(status)) {
// Skip draining hosts if not in the override status set.
if (status.status() == XdsHealthStatus::kDraining &&
!config_->override_host_status_set().Contains(status)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
gpr_log(GPR_INFO,
"[xds_override_host_lb %p] endpoint %s: draining but not in "
"override_host_status set -- ignoring",
this, endpoint.ToString().c_str());
}
continue;
return;
}
std::vector<std::string> addresses;
addresses.reserve(endpoint.addresses().size());
@ -641,7 +659,7 @@ absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
std::piecewise_construct, std::forward_as_tuple(addresses[i]),
std::forward_as_tuple(status, std::move(address_list)));
}
}
});
// Now grab the lock and update subchannel_map_ from addresses_for_map.
{
MutexLock lock(&subchannel_map_mu_);
@ -688,7 +706,6 @@ absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
it->second.set_address_list(std::move(address_info.address_list));
}
}
return child_addresses;
}
RefCountedPtr<XdsOverrideHostLb::SubchannelWrapper>

@ -21,7 +21,6 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
@ -170,10 +169,10 @@ absl::Status XdsWrrLocalityLb::UpdateLocked(UpdateArgs args) {
// Scan the addresses to find the weight for each locality.
std::map<std::string, uint32_t> locality_weights;
if (args.addresses.ok()) {
for (const auto& address : *args.addresses) {
auto* locality_name = address.args().GetObject<XdsLocalityName>();
(*args.addresses)->ForEach([&](const EndpointAddresses& endpoint) {
auto* locality_name = endpoint.args().GetObject<XdsLocalityName>();
uint32_t weight =
address.args().GetInt(GRPC_ARG_XDS_LOCALITY_WEIGHT).value_or(0);
endpoint.args().GetInt(GRPC_ARG_XDS_LOCALITY_WEIGHT).value_or(0);
if (locality_name != nullptr && weight > 0) {
auto p = locality_weights.emplace(
locality_name->AsHumanReadableString(), weight);
@ -184,7 +183,7 @@ absl::Status XdsWrrLocalityLb::UpdateLocked(UpdateArgs args) {
p.first->first.c_str(), p.first->second, weight);
}
}
}
});
}
// Construct the config for the weighted_target policy.
Json::Object weighted_targets;

@ -22,10 +22,9 @@
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include <memory>
#include <type_traits>
#include <utility>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include <grpc/support/log.h>
@ -36,9 +35,7 @@
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/work_serializer.h"
#include "src/core/lib/resolver/endpoint_addresses.h"
#include "src/core/lib/resolver/resolver_factory.h"
#include "src/core/lib/service_config/service_config.h"
#include "src/core/lib/uri/uri_parser.h"
namespace grpc_core {
@ -55,47 +52,38 @@ class FakeResolver : public Resolver {
private:
friend class FakeResolverResponseGenerator;
friend class FakeResolverResponseSetter;
void ShutdownLocked() override;
void MaybeSendResultLocked();
void ReturnReresolutionResult();
// passed-in parameters
ChannelArgs channel_args_;
std::shared_ptr<WorkSerializer> work_serializer_;
std::unique_ptr<ResultHandler> result_handler_;
ChannelArgs channel_args_;
RefCountedPtr<FakeResolverResponseGenerator> response_generator_;
// If has_next_result_ is true, next_result_ is the next resolution result
// to be returned.
bool has_next_result_ = false;
Result next_result_;
// Result to use for the pretended re-resolution in
// RequestReresolutionLocked().
bool has_reresolution_result_ = false;
Result reresolution_result_;
// The next resolution result to be returned, if any. Present when we
// get a result before the resolver is started.
absl::optional<Result> next_result_;
// True after the call to StartLocked().
bool started_ = false;
// True after the call to ShutdownLocked().
bool shutdown_ = false;
// if true, return failure
bool return_failure_ = false;
// pending re-resolution
bool reresolution_closure_pending_ = false;
};
FakeResolver::FakeResolver(ResolverArgs args)
: work_serializer_(std::move(args.work_serializer)),
result_handler_(std::move(args.result_handler)),
channel_args_(
// Channels sharing the same subchannels may have different resolver
// response generators. If we don't remove this arg, subchannel pool
// will create new subchannels for the same address instead of
// reusing existing ones because of different values of this channel
// arg. Can't just use GRPC_ARG_NO_SUBCHANNEL_PREFIX, since
// that can't be passed into the channel from test code.
args.args.Remove(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR)),
response_generator_(
args.args.GetObjectRef<FakeResolverResponseGenerator>()) {
// Channels sharing the same subchannels may have different resolver response
// generators. If we don't remove this arg, subchannel pool will create new
// subchannels for the same address instead of reusing existing ones because
// of different values of this channel arg.
channel_args_ = args.args.Remove(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
if (response_generator_ != nullptr) {
response_generator_->SetFakeResolver(Ref());
}
@ -107,19 +95,9 @@ void FakeResolver::StartLocked() {
}
void FakeResolver::RequestReresolutionLocked() {
if (has_reresolution_result_ || return_failure_) {
next_result_ = reresolution_result_;
has_next_result_ = true;
// Return the result in a different closure, so that we don't call
// back into the LB policy while it's still processing the previous
// update.
if (!reresolution_closure_pending_) {
reresolution_closure_pending_ = true;
Ref().release(); // ref held by closure
work_serializer_->Run([this]() { ReturnReresolutionResult(); },
DEBUG_LOCATION);
}
}
// Re-resolution can't happen until after we return an initial result.
GPR_ASSERT(response_generator_ != nullptr);
response_generator_->ReresolutionRequested();
}
void FakeResolver::ShutdownLocked() {
@ -132,80 +110,15 @@ void FakeResolver::ShutdownLocked() {
void FakeResolver::MaybeSendResultLocked() {
if (!started_ || shutdown_) return;
if (return_failure_) {
// TODO(roth): Change resolver result generator to be able to inject
// the error to be returned and to be able to independently set errors
// for addresses and service config.
Result result;
result.addresses = absl::UnavailableError("Resolver transient failure");
result.service_config = result.addresses.status();
result.args = channel_args_;
result_handler_->ReportResult(std::move(result));
return_failure_ = false;
} else if (has_next_result_) {
if (next_result_.has_value()) {
// When both next_results_ and channel_args_ contain an arg with the same
// name, only the one in next_results_.
next_result_.args = next_result_.args.UnionWith(channel_args_);
result_handler_->ReportResult(std::move(next_result_));
has_next_result_ = false;
// name, use the one in next_results_.
next_result_->args = next_result_->args.UnionWith(channel_args_);
result_handler_->ReportResult(std::move(*next_result_));
next_result_.reset();
}
}
void FakeResolver::ReturnReresolutionResult() {
reresolution_closure_pending_ = false;
MaybeSendResultLocked();
Unref();
}
class FakeResolverResponseSetter {
public:
explicit FakeResolverResponseSetter(RefCountedPtr<FakeResolver> resolver,
Resolver::Result result,
bool has_result = false,
bool immediate = true)
: resolver_(std::move(resolver)),
result_(std::move(result)),
has_result_(has_result),
immediate_(immediate) {}
void SetResponseLocked();
void SetReresolutionResponseLocked();
void SetFailureLocked();
private:
RefCountedPtr<FakeResolver> resolver_;
Resolver::Result result_;
bool has_result_;
bool immediate_;
};
// Deletes object when done
void FakeResolverResponseSetter::SetReresolutionResponseLocked() {
if (!resolver_->shutdown_) {
resolver_->reresolution_result_ = std::move(result_);
resolver_->has_reresolution_result_ = has_result_;
}
delete this;
}
// Deletes object when done
void FakeResolverResponseSetter::SetResponseLocked() {
if (!resolver_->shutdown_) {
resolver_->next_result_ = std::move(result_);
resolver_->has_next_result_ = true;
resolver_->MaybeSendResultLocked();
}
delete this;
}
// Deletes object when done
void FakeResolverResponseSetter::SetFailureLocked() {
if (!resolver_->shutdown_) {
resolver_->return_failure_ = true;
if (immediate_) resolver_->MaybeSendResultLocked();
}
delete this;
}
//
// FakeResolverResponseGenerator
//
@ -220,101 +133,73 @@ void FakeResolverResponseGenerator::SetResponseAndNotify(
{
MutexLock lock(&mu_);
if (resolver_ == nullptr) {
has_result_ = true;
result_ = std::move(result);
if (notify_when_set != nullptr) notify_when_set->Notify();
return;
}
resolver = resolver_->Ref();
}
FakeResolverResponseSetter* arg =
new FakeResolverResponseSetter(resolver, std::move(result));
resolver->work_serializer_->Run(
[arg, notify_when_set]() {
arg->SetResponseLocked();
if (notify_when_set != nullptr) notify_when_set->Notify();
},
DEBUG_LOCATION);
SendResultToResolver(std::move(resolver), std::move(result), notify_when_set);
}
void FakeResolverResponseGenerator::SetReresolutionResponseAndNotify(
Resolver::Result result, Notification* notify_when_set) {
RefCountedPtr<FakeResolver> resolver;
void FakeResolverResponseGenerator::SetFakeResolver(
RefCountedPtr<FakeResolver> resolver) {
Resolver::Result result;
{
MutexLock lock(&mu_);
GPR_ASSERT(resolver_ != nullptr);
resolver = resolver_->Ref();
resolver_ = resolver;
if (resolver_set_cv_ != nullptr) resolver_set_cv_->SignalAll();
if (resolver == nullptr) return;
if (!result_.has_value()) return;
result = std::move(*result_);
result_.reset();
}
SendResultToResolver(std::move(resolver), std::move(result), nullptr);
}
void FakeResolverResponseGenerator::SendResultToResolver(
RefCountedPtr<FakeResolver> resolver, Resolver::Result result,
Notification* notify_when_set) {
auto* resolver_ptr = resolver.get();
resolver_ptr->work_serializer_->Run(
[resolver = std::move(resolver), result = std::move(result),
notify_when_set]() mutable {
if (!resolver->shutdown_) {
resolver->next_result_ = std::move(result);
resolver->MaybeSendResultLocked();
}
FakeResolverResponseSetter* arg = new FakeResolverResponseSetter(
resolver, std::move(result), true /* has_result */);
resolver->work_serializer_->Run(
[arg, notify_when_set]() {
arg->SetReresolutionResponseLocked();
if (notify_when_set != nullptr) notify_when_set->Notify();
},
DEBUG_LOCATION);
}
void FakeResolverResponseGenerator::UnsetReresolutionResponse() {
RefCountedPtr<FakeResolver> resolver;
{
MutexLock lock(&mu_);
GPR_ASSERT(resolver_ != nullptr);
resolver = resolver_->Ref();
}
FakeResolverResponseSetter* arg =
new FakeResolverResponseSetter(resolver, Resolver::Result());
resolver->work_serializer_->Run(
[arg]() { arg->SetReresolutionResponseLocked(); }, DEBUG_LOCATION);
}
void FakeResolverResponseGenerator::SetFailure() {
RefCountedPtr<FakeResolver> resolver;
{
MutexLock lock(&mu_);
GPR_ASSERT(resolver_ != nullptr);
resolver = resolver_->Ref();
}
FakeResolverResponseSetter* arg =
new FakeResolverResponseSetter(resolver, Resolver::Result());
resolver->work_serializer_->Run([arg]() { arg->SetFailureLocked(); },
DEBUG_LOCATION);
}
void FakeResolverResponseGenerator::SetFailureOnReresolution() {
RefCountedPtr<FakeResolver> resolver;
{
bool FakeResolverResponseGenerator::WaitForResolverSet(absl::Duration timeout) {
MutexLock lock(&mu_);
GPR_ASSERT(resolver_ != nullptr);
resolver = resolver_->Ref();
if (resolver_ == nullptr) {
CondVar condition;
resolver_set_cv_ = &condition;
condition.WaitWithTimeout(&mu_, timeout);
resolver_set_cv_ = nullptr;
}
FakeResolverResponseSetter* arg = new FakeResolverResponseSetter(
resolver, Resolver::Result(), false /* has_result */,
false /* immediate */);
resolver->work_serializer_->Run([arg]() { arg->SetFailureLocked(); },
DEBUG_LOCATION);
return resolver_ != nullptr;
}
void FakeResolverResponseGenerator::SetFakeResolver(
RefCountedPtr<FakeResolver> resolver) {
MutexLock lock(&mu_);
resolver_ = std::move(resolver);
cv_.SignalAll();
if (resolver_ == nullptr) return;
if (has_result_) {
FakeResolverResponseSetter* arg =
new FakeResolverResponseSetter(resolver_, std::move(result_));
resolver_->work_serializer_->Run([arg]() { arg->SetResponseLocked(); },
DEBUG_LOCATION);
has_result_ = false;
bool FakeResolverResponseGenerator::WaitForReresolutionRequest(
absl::Duration timeout) {
MutexLock lock(&reresolution_mu_);
if (!reresolution_requested_) {
CondVar condition;
reresolution_cv_ = &condition;
condition.WaitWithTimeout(&reresolution_mu_, timeout);
reresolution_cv_ = nullptr;
}
return std::exchange(reresolution_requested_, false);
}
void FakeResolverResponseGenerator::WaitForResolverSet() {
MutexLock lock(&mu_);
while (resolver_ == nullptr) {
cv_.Wait(&mu_);
}
void FakeResolverResponseGenerator::ReresolutionRequested() {
MutexLock lock(&reresolution_mu_);
reresolution_requested_ = true;
if (reresolution_cv_ != nullptr) reresolution_cv_->SignalAll();
}
namespace {
@ -341,22 +226,6 @@ const grpc_arg_pointer_vtable
ResponseGeneratorChannelArgCopy, ResponseGeneratorChannelArgDestroy,
ResponseGeneratorChannelArgCmp};
grpc_arg FakeResolverResponseGenerator::MakeChannelArg(
FakeResolverResponseGenerator* generator) {
return grpc_channel_arg_pointer_create(
const_cast<char*>(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR), generator,
&kChannelArgPointerVtable);
}
RefCountedPtr<FakeResolverResponseGenerator>
FakeResolverResponseGenerator::GetFromArgs(const grpc_channel_args* args) {
auto* response_generator =
grpc_channel_args_find_pointer<FakeResolverResponseGenerator>(
args, GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
if (response_generator == nullptr) return nullptr;
return response_generator->Ref();
}
//
// Factory
//

@ -23,6 +23,8 @@
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include <grpc/grpc.h>
@ -42,8 +44,7 @@ class FakeResolver;
/// A mechanism for generating responses for the fake resolver.
/// An instance of this class is passed to the fake resolver via a channel
/// argument (see \a MakeChannelArg()) and used to inject and trigger custom
/// resolutions.
/// argument and used to inject and trigger custom resolutions.
// TODO(roth): I would ideally like this to be InternallyRefCounted
// instead of RefCounted, but external refs are currently needed to
// encode this in channel args. Once channel_args are converted to C++,
@ -77,50 +78,20 @@ class FakeResolverResponseGenerator
n.WaitForNotification();
}
// Sets the re-resolution response, which is returned by the fake resolver
// when re-resolution is requested (via \a RequestReresolutionLocked()).
// The new re-resolution response replaces any previous re-resolution
// response that may have been set by a previous call.
// notify_when_set is an optional notification to signal when the response has
// been set.
void SetReresolutionResponseAndNotify(Resolver::Result result,
Notification* notify_when_set);
void SetReresolutionResponseAsync(Resolver::Result result) {
SetReresolutionResponseAndNotify(std::move(result), nullptr);
}
void SetReresolutionResponseSynchronously(Resolver::Result result) {
Notification n;
SetReresolutionResponseAndNotify(std::move(result), &n);
n.WaitForNotification();
}
// Unsets the re-resolution response. After this, the fake resolver will
// not return anything when \a RequestReresolutionLocked() is called.
void UnsetReresolutionResponse();
// Tells the resolver to return a transient failure.
void SetFailure();
// Same as SetFailure(), but instead of returning the error
// immediately, waits for the next call to RequestReresolutionLocked().
void SetFailureOnReresolution();
// Returns a channel arg containing \a generator.
// TODO(roth): When we have time, make this a non-static method.
static grpc_arg MakeChannelArg(FakeResolverResponseGenerator* generator);
// Waits up to timeout for a re-resolution request. Returns true if a
// re-resolution request is seen, or false if timeout occurs. Returns
// true immediately if there was a re-resolution request since the
// last time this method was called.
bool WaitForReresolutionRequest(absl::Duration timeout);
// Returns the response generator in \a args, or null if not found.
static RefCountedPtr<FakeResolverResponseGenerator> GetFromArgs(
const grpc_channel_args* args);
// Wait for a resolver to be set (setting may be happening asynchronously, so
// this may block - consider it test only).
bool WaitForResolverSet(absl::Duration timeout);
static absl::string_view ChannelArgName() {
return GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
}
// Wait for a resolver to be set (setting may be happening asynchronously, so
// this may block - consider it test only).
void WaitForResolverSet();
static int ChannelArgsCompare(const FakeResolverResponseGenerator* a,
const FakeResolverResponseGenerator* b) {
return QsortCompare(a, b);
@ -128,15 +99,29 @@ class FakeResolverResponseGenerator
private:
friend class FakeResolver;
// Set the corresponding FakeResolver to this generator.
void SetFakeResolver(RefCountedPtr<FakeResolver> resolver);
// Called by FakeResolver when re-resolution is requested.
void ReresolutionRequested();
// Helper function to send a result to the resolver.
static void SendResultToResolver(RefCountedPtr<FakeResolver> resolver,
Resolver::Result result,
Notification* notify_when_set);
// Mutex protecting the members below.
Mutex mu_;
CondVar cv_;
CondVar* resolver_set_cv_ ABSL_GUARDED_BY(mu_) = nullptr;
RefCountedPtr<FakeResolver> resolver_ ABSL_GUARDED_BY(mu_);
Resolver::Result result_ ABSL_GUARDED_BY(mu_);
bool has_result_ ABSL_GUARDED_BY(mu_) = false;
// Temporarily stores the result when it gets set before the response
// generator is seen by the FakeResolver.
absl::optional<Resolver::Result> result_ ABSL_GUARDED_BY(mu_);
Mutex reresolution_mu_;
CondVar* reresolution_cv_ ABSL_GUARDED_BY(reresolution_mu_) = nullptr;
bool reresolution_requested_ ABSL_GUARDED_BY(reresolution_mu_) = false;
};
} // namespace grpc_core

@ -143,6 +143,7 @@ const RetryMethodConfig* RetryFilter::GetRetryPolicy(
const grpc_channel_filter RetryFilter::kVtable = {
RetryFilter::LegacyCallData::StartTransportStreamOpBatch,
nullptr,
/* init_call: */ nullptr,
RetryFilter::StartTransportOp,
sizeof(RetryFilter::LegacyCallData),
RetryFilter::LegacyCallData::Init,

@ -343,6 +343,7 @@ const grpc_channel_filter grpc_client_deadline_filter = {
grpc_core::NextPromiseFactory next_promise_factory) {
return next_promise_factory(std::move(call_args));
},
/* init_call: */ nullptr,
grpc_channel_next_op,
sizeof(grpc_deadline_state),
deadline_init_call_elem,
@ -368,6 +369,17 @@ const grpc_channel_filter grpc_server_deadline_filter = {
}
return next_promise_factory(std::move(call_args));
},
[](grpc_channel_element*, grpc_core::CallSpineInterface* spine) {
spine->client_initial_metadata().receiver.InterceptAndMap(
[](grpc_core::ClientMetadataHandle md) {
auto deadline = md->get(grpc_core::GrpcTimeoutMetadata());
if (deadline.has_value()) {
grpc_core::GetContext<grpc_core::CallContext>()->UpdateDeadline(
*deadline);
}
return md;
});
},
grpc_channel_next_op,
sizeof(server_call_data),
deadline_init_call_elem,

@ -51,6 +51,10 @@
namespace grpc_core {
const NoInterceptor HttpClientFilter::Call::OnServerToClientMessage;
const NoInterceptor HttpClientFilter::Call::OnClientToServerMessage;
const NoInterceptor HttpClientFilter::Call::OnFinalize;
const grpc_channel_filter HttpClientFilter::kFilter =
MakePromiseBasedFilter<HttpClientFilter, FilterEndpoint::kClient,
kFilterExaminesServerInitialMetadata>("http-client");
@ -105,40 +109,27 @@ Slice UserAgentFromArgs(const ChannelArgs& args,
}
} // namespace
ArenaPromise<ServerMetadataHandle> HttpClientFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
auto& md = call_args.client_initial_metadata;
if (test_only_use_put_requests_) {
md->Set(HttpMethodMetadata(), HttpMethodMetadata::kPut);
void HttpClientFilter::Call::OnClientInitialMetadata(ClientMetadata& md,
HttpClientFilter* filter) {
if (filter->test_only_use_put_requests_) {
md.Set(HttpMethodMetadata(), HttpMethodMetadata::kPut);
} else {
md->Set(HttpMethodMetadata(), HttpMethodMetadata::kPost);
}
md->Set(HttpSchemeMetadata(), scheme_);
md->Set(TeMetadata(), TeMetadata::kTrailers);
md->Set(ContentTypeMetadata(), ContentTypeMetadata::kApplicationGrpc);
md->Set(UserAgentMetadata(), user_agent_.Ref());
auto* initial_metadata_err =
GetContext<Arena>()->New<Latch<ServerMetadataHandle>>();
call_args.server_initial_metadata->InterceptAndMap(
[initial_metadata_err](
ServerMetadataHandle md) -> absl::optional<ServerMetadataHandle> {
auto r = CheckServerMetadata(md.get());
if (!r.ok()) {
initial_metadata_err->Set(ServerMetadataFromStatus(r));
return absl::nullopt;
md.Set(HttpMethodMetadata(), HttpMethodMetadata::kPost);
}
return std::move(md);
});
return Race(initial_metadata_err->Wait(),
Map(next_promise_factory(std::move(call_args)),
[](ServerMetadataHandle md) -> ServerMetadataHandle {
auto r = CheckServerMetadata(md.get());
if (!r.ok()) return ServerMetadataFromStatus(r);
return md;
}));
md.Set(HttpSchemeMetadata(), filter->scheme_);
md.Set(TeMetadata(), TeMetadata::kTrailers);
md.Set(ContentTypeMetadata(), ContentTypeMetadata::kApplicationGrpc);
md.Set(UserAgentMetadata(), filter->user_agent_.Ref());
}
absl::Status HttpClientFilter::Call::OnServerInitialMetadata(
ServerMetadata& md) {
return CheckServerMetadata(&md);
}
absl::Status HttpClientFilter::Call::OnServerTrailingMetadata(
ServerMetadata& md) {
return CheckServerMetadata(&md);
}
HttpClientFilter::HttpClientFilter(HttpSchemeMetadata::ValueType scheme,

@ -25,23 +25,28 @@
#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"
#include "src/core/lib/promise/arena_promise.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
class HttpClientFilter : public ChannelFilter {
class HttpClientFilter : public ImplementChannelFilter<HttpClientFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<HttpClientFilter> 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, HttpClientFilter* filter);
absl::Status OnServerInitialMetadata(ServerMetadata& md);
absl::Status OnServerTrailingMetadata(ServerMetadata& md);
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
HttpClientFilter(HttpSchemeMetadata::ValueType scheme, Slice user_agent,

@ -49,6 +49,10 @@
namespace grpc_core {
const NoInterceptor HttpServerFilter::Call::OnClientToServerMessage;
const NoInterceptor HttpServerFilter::Call::OnServerToClientMessage;
const NoInterceptor HttpServerFilter::Call::OnFinalize;
const grpc_channel_filter HttpServerFilter::kFilter =
MakePromiseBasedFilter<HttpServerFilter, FilterEndpoint::kServer,
kFilterExaminesServerInitialMetadata>("http-server");
@ -71,85 +75,81 @@ ServerMetadataHandle MalformedRequest(absl::string_view explanation) {
}
} // namespace
ArenaPromise<ServerMetadataHandle> HttpServerFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
const auto& md = call_args.client_initial_metadata;
auto method = md->get(HttpMethodMetadata());
ServerMetadataHandle HttpServerFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, HttpServerFilter* filter) {
auto method = md.get(HttpMethodMetadata());
if (method.has_value()) {
switch (*method) {
case HttpMethodMetadata::kPost:
break;
case HttpMethodMetadata::kPut:
if (allow_put_requests_) {
if (filter->allow_put_requests_) {
break;
}
ABSL_FALLTHROUGH_INTENDED;
case HttpMethodMetadata::kInvalid:
case HttpMethodMetadata::kGet:
return Immediate(MalformedRequest("Bad method header"));
return MalformedRequest("Bad method header");
}
} else {
return Immediate(MalformedRequest("Missing :method header"));
return MalformedRequest("Missing :method header");
}
auto te = md->Take(TeMetadata());
auto te = md.Take(TeMetadata());
if (te == TeMetadata::kTrailers) {
// Do nothing, ok.
} else if (!te.has_value()) {
return Immediate(MalformedRequest("Missing :te header"));
return MalformedRequest("Missing :te header");
} else {
return Immediate(MalformedRequest("Bad :te header"));
return MalformedRequest("Bad :te header");
}
auto scheme = md->Take(HttpSchemeMetadata());
auto scheme = md.Take(HttpSchemeMetadata());
if (scheme.has_value()) {
if (*scheme == HttpSchemeMetadata::kInvalid) {
return Immediate(MalformedRequest("Bad :scheme header"));
return MalformedRequest("Bad :scheme header");
}
} else {
return Immediate(MalformedRequest("Missing :scheme header"));
return MalformedRequest("Missing :scheme header");
}
md->Remove(ContentTypeMetadata());
md.Remove(ContentTypeMetadata());
Slice* path_slice = md->get_pointer(HttpPathMetadata());
Slice* path_slice = md.get_pointer(HttpPathMetadata());
if (path_slice == nullptr) {
return Immediate(MalformedRequest("Missing :path header"));
return MalformedRequest("Missing :path header");
}
if (md->get_pointer(HttpAuthorityMetadata()) == nullptr) {
absl::optional<Slice> host = md->Take(HostMetadata());
if (md.get_pointer(HttpAuthorityMetadata()) == nullptr) {
absl::optional<Slice> host = md.Take(HostMetadata());
if (host.has_value()) {
md->Set(HttpAuthorityMetadata(), std::move(*host));
md.Set(HttpAuthorityMetadata(), std::move(*host));
}
}
if (md->get_pointer(HttpAuthorityMetadata()) == nullptr) {
return Immediate(MalformedRequest("Missing :authority header"));
if (md.get_pointer(HttpAuthorityMetadata()) == nullptr) {
return MalformedRequest("Missing :authority header");
}
if (!surface_user_agent_) {
md->Remove(UserAgentMetadata());
if (!filter->surface_user_agent_) {
md.Remove(UserAgentMetadata());
}
call_args.server_initial_metadata->InterceptAndMap(
[](ServerMetadataHandle md) {
return nullptr;
}
void HttpServerFilter::Call::OnServerInitialMetadata(ServerMetadata& md) {
if (grpc_call_trace.enabled()) {
gpr_log(GPR_INFO, "%s[http-server] Write metadata",
Activity::current()->DebugTag().c_str());
}
FilterOutgoingMetadata(md.get());
md->Set(HttpStatusMetadata(), 200);
md->Set(ContentTypeMetadata(), ContentTypeMetadata::kApplicationGrpc);
return md;
});
return Map(next_promise_factory(std::move(call_args)),
[](ServerMetadataHandle md) -> ServerMetadataHandle {
FilterOutgoingMetadata(md.get());
return md;
});
FilterOutgoingMetadata(&md);
md.Set(HttpStatusMetadata(), 200);
md.Set(ContentTypeMetadata(), ContentTypeMetadata::kApplicationGrpc);
}
void HttpServerFilter::Call::OnServerTrailingMetadata(ServerMetadata& md) {
FilterOutgoingMetadata(&md);
}
absl::StatusOr<HttpServerFilter> HttpServerFilter::Create(

@ -32,16 +32,23 @@
namespace grpc_core {
// Processes metadata on the server side for HTTP2 transports
class HttpServerFilter : public ChannelFilter {
class HttpServerFilter : public ImplementChannelFilter<HttpServerFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<HttpServerFilter> 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:
ServerMetadataHandle OnClientInitialMetadata(ClientMetadata& md,
HttpServerFilter* filter);
void OnServerInitialMetadata(ServerMetadata& md);
void OnServerTrailingMetadata(ServerMetadata& md);
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
};
private:
HttpServerFilter(bool surface_user_agent, bool allow_put_requests)

@ -50,6 +50,15 @@
namespace grpc_core {
const NoInterceptor ClientMessageSizeFilter::Call::OnClientInitialMetadata;
const NoInterceptor ClientMessageSizeFilter::Call::OnServerInitialMetadata;
const NoInterceptor ClientMessageSizeFilter::Call::OnServerTrailingMetadata;
const NoInterceptor ClientMessageSizeFilter::Call::OnFinalize;
const NoInterceptor ServerMessageSizeFilter::Call::OnClientInitialMetadata;
const NoInterceptor ServerMessageSizeFilter::Call::OnServerInitialMetadata;
const NoInterceptor ServerMessageSizeFilter::Call::OnServerTrailingMetadata;
const NoInterceptor ServerMessageSizeFilter::Call::OnFinalize;
//
// MessageSizeParsedConfig
//
@ -138,60 +147,6 @@ const grpc_channel_filter ServerMessageSizeFilter::kFilter =
kFilterExaminesOutboundMessages |
kFilterExaminesInboundMessages>("message_size");
class MessageSizeFilter::CallBuilder {
private:
auto Interceptor(uint32_t max_length, bool is_send) {
return [max_length, is_send,
err = err_](MessageHandle msg) -> absl::optional<MessageHandle> {
if (grpc_call_trace.enabled()) {
gpr_log(GPR_INFO, "%s[message_size] %s len:%" PRIdPTR " max:%d",
Activity::current()->DebugTag().c_str(),
is_send ? "send" : "recv", msg->payload()->Length(),
max_length);
}
if (msg->payload()->Length() > max_length) {
if (err->is_set()) return std::move(msg);
auto r = GetContext<Arena>()->MakePooled<ServerMetadata>(
GetContext<Arena>());
r->Set(GrpcStatusMetadata(), GRPC_STATUS_RESOURCE_EXHAUSTED);
r->Set(GrpcMessageMetadata(),
Slice::FromCopiedString(
absl::StrFormat("%s message larger than max (%u vs. %d)",
is_send ? "Sent" : "Received",
msg->payload()->Length(), max_length)));
err->Set(std::move(r));
return absl::nullopt;
}
return std::move(msg);
};
}
public:
explicit CallBuilder(const MessageSizeParsedConfig& limits)
: limits_(limits) {}
template <typename T>
void AddSend(T* pipe_end) {
if (!limits_.max_send_size().has_value()) return;
pipe_end->InterceptAndMap(Interceptor(*limits_.max_send_size(), true));
}
template <typename T>
void AddRecv(T* pipe_end) {
if (!limits_.max_recv_size().has_value()) return;
pipe_end->InterceptAndMap(Interceptor(*limits_.max_recv_size(), false));
}
ArenaPromise<ServerMetadataHandle> Run(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
return Race(err_->Wait(), next_promise_factory(std::move(call_args)));
}
private:
Latch<ServerMetadataHandle>* const err_ =
GetContext<Arena>()->ManagedNew<Latch<ServerMetadataHandle>>();
MessageSizeParsedConfig limits_;
};
absl::StatusOr<ClientMessageSizeFilter> ClientMessageSizeFilter::Create(
const ChannelArgs& args, ChannelFilter::Args) {
return ClientMessageSizeFilter(args);
@ -202,20 +157,40 @@ absl::StatusOr<ServerMessageSizeFilter> ServerMessageSizeFilter::Create(
return ServerMessageSizeFilter(args);
}
ArenaPromise<ServerMetadataHandle> ClientMessageSizeFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
namespace {
ServerMetadataHandle CheckPayload(const Message& msg,
absl::optional<uint32_t> max_length,
bool is_send) {
if (!max_length.has_value()) return nullptr;
if (GRPC_TRACE_FLAG_ENABLED(grpc_call_trace)) {
gpr_log(GPR_INFO, "%s[message_size] %s len:%" PRIdPTR " max:%d",
Activity::current()->DebugTag().c_str(), is_send ? "send" : "recv",
msg.payload()->Length(), *max_length);
}
if (msg.payload()->Length() <= *max_length) return nullptr;
auto r = GetContext<Arena>()->MakePooled<ServerMetadata>(GetContext<Arena>());
r->Set(GrpcStatusMetadata(), GRPC_STATUS_RESOURCE_EXHAUSTED);
r->Set(GrpcMessageMetadata(), Slice::FromCopiedString(absl::StrFormat(
"%s message larger than max (%u vs. %d)",
is_send ? "Sent" : "Received",
msg.payload()->Length(), *max_length)));
return r;
}
} // namespace
ClientMessageSizeFilter::Call::Call(ClientMessageSizeFilter* filter)
: limits_(filter->parsed_config_) {
// Get max sizes from channel data, then merge in per-method config values.
// Note: Per-method config is only available on the client, so we
// apply the max request size to the send limit and the max response
// size to the receive limit.
MessageSizeParsedConfig limits = this->limits();
const MessageSizeParsedConfig* config_from_call_context =
MessageSizeParsedConfig::GetFromCallContext(
GetContext<grpc_call_context_element>(),
service_config_parser_index_);
filter->service_config_parser_index_);
if (config_from_call_context != nullptr) {
absl::optional<uint32_t> max_send_size = limits.max_send_size();
absl::optional<uint32_t> max_recv_size = limits.max_recv_size();
absl::optional<uint32_t> max_send_size = limits_.max_send_size();
absl::optional<uint32_t> max_recv_size = limits_.max_recv_size();
if (config_from_call_context->max_send_size().has_value() &&
(!max_send_size.has_value() ||
*config_from_call_context->max_send_size() < *max_send_size)) {
@ -226,21 +201,28 @@ ArenaPromise<ServerMetadataHandle> ClientMessageSizeFilter::MakeCallPromise(
*config_from_call_context->max_recv_size() < *max_recv_size)) {
max_recv_size = *config_from_call_context->max_recv_size();
}
limits = MessageSizeParsedConfig(max_send_size, max_recv_size);
limits_ = MessageSizeParsedConfig(max_send_size, max_recv_size);
}
}
ServerMetadataHandle ServerMessageSizeFilter::Call::OnClientToServerMessage(
const Message& message, ServerMessageSizeFilter* filter) {
return CheckPayload(message, filter->parsed_config_.max_recv_size(), false);
}
ServerMetadataHandle ServerMessageSizeFilter::Call::OnServerToClientMessage(
const Message& message, ServerMessageSizeFilter* filter) {
return CheckPayload(message, filter->parsed_config_.max_send_size(), true);
}
CallBuilder b(limits);
b.AddSend(call_args.client_to_server_messages);
b.AddRecv(call_args.server_to_client_messages);
return b.Run(std::move(call_args), std::move(next_promise_factory));
ServerMetadataHandle ClientMessageSizeFilter::Call::OnClientToServerMessage(
const Message& message) {
return CheckPayload(message, limits_.max_send_size(), true);
}
ArenaPromise<ServerMetadataHandle> ServerMessageSizeFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
CallBuilder b(limits());
b.AddSend(call_args.server_to_client_messages);
b.AddRecv(call_args.client_to_server_messages);
return b.Run(std::move(call_args), std::move(next_promise_factory));
ServerMetadataHandle ClientMessageSizeFilter::Call::OnServerToClientMessage(
const Message& message) {
return CheckPayload(message, limits_.max_recv_size(), false);
}
namespace {

@ -86,48 +86,60 @@ class MessageSizeParser : public ServiceConfigParser::Parser {
absl::optional<uint32_t> GetMaxRecvSizeFromChannelArgs(const ChannelArgs& args);
absl::optional<uint32_t> GetMaxSendSizeFromChannelArgs(const ChannelArgs& args);
class MessageSizeFilter : public ChannelFilter {
protected:
explicit MessageSizeFilter(const ChannelArgs& args)
: limits_(MessageSizeParsedConfig::GetFromChannelArgs(args)) {}
class CallBuilder;
const MessageSizeParsedConfig& limits() const { return limits_; }
private:
MessageSizeParsedConfig limits_;
};
class ServerMessageSizeFilter final : public MessageSizeFilter {
class ServerMessageSizeFilter final
: public ImplementChannelFilter<ServerMessageSizeFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<ServerMessageSizeFilter> 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:
static const NoInterceptor OnClientInitialMetadata;
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnFinalize;
ServerMetadataHandle OnClientToServerMessage(
const Message& message, ServerMessageSizeFilter* filter);
ServerMetadataHandle OnServerToClientMessage(
const Message& message, ServerMessageSizeFilter* filter);
};
private:
using MessageSizeFilter::MessageSizeFilter;
explicit ServerMessageSizeFilter(const ChannelArgs& args)
: parsed_config_(MessageSizeParsedConfig::GetFromChannelArgs(args)) {}
const MessageSizeParsedConfig parsed_config_;
};
class ClientMessageSizeFilter final : public MessageSizeFilter {
class ClientMessageSizeFilter final
: public ImplementChannelFilter<ClientMessageSizeFilter> {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<ClientMessageSizeFilter> 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:
explicit Call(ClientMessageSizeFilter* filter);
static const NoInterceptor OnClientInitialMetadata;
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnFinalize;
ServerMetadataHandle OnClientToServerMessage(const Message& message);
ServerMetadataHandle OnServerToClientMessage(const Message& message);
private:
MessageSizeParsedConfig limits_;
};
private:
explicit ClientMessageSizeFilter(const ChannelArgs& args)
: parsed_config_(MessageSizeParsedConfig::GetFromChannelArgs(args)) {}
const size_t service_config_parser_index_{MessageSizeParser::ParserIndex()};
using MessageSizeFilter::MessageSizeFilter;
const MessageSizeParsedConfig parsed_config_;
};
} // namespace grpc_core

@ -20,17 +20,26 @@
#include <string>
#include <tuple>
#include "absl/random/bit_gen_ref.h"
#include "absl/random/random.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/match.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/join.h"
#include "src/core/lib/promise/loop.h"
#include "src/core/lib/promise/try_join.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/slice/slice_internal.h"
@ -49,9 +58,15 @@ ClientTransport::ClientTransport(
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] {
return Seq(
return TrySeq(
// Get next outgoing frame.
this->outgoing_frames_.Next(),
// Construct data buffers that will be sent to the endpoints.
@ -81,30 +96,93 @@ ClientTransport::ClientTransport(
},
// Write buffers to corresponding endpoints concurrently.
[this]() {
return Join(this->control_endpoint_->Write(
return TryJoin(
control_endpoint_->Write(
std::move(control_endpoint_write_buffer_)),
this->data_endpoint_->Write(
std::move(data_endpoint_write_buffer_)));
data_endpoint_->Write(std::move(data_endpoint_write_buffer_)));
},
// Finish writes and return status.
[](std::tuple<absl::Status, absl::Status> ret)
-> LoopCtl<absl::Status> {
// If writes failed, return failure status.
if (!(std::get<0>(ret).ok() || std::get<1>(ret).ok())) {
// TODO(ladynana): handle the promise endpoint write failures with
// closing the transport.
return absl::InternalError("Promise endpoint writes failed.");
}
// 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
// function.
return Continue();
});
});
writer_ = MakeActivity(
// Continuously write next outgoing frames to promise endpoints.
std::move(write_loop), EventEngineWakeupScheduler(event_engine_),
[](absl::Status status) {
GPR_ASSERT(status.code() == absl::StatusCode::kCancelled ||
status.code() == absl::StatusCode::kInternal);
[this](absl::Status status) {
if (!(status.ok() || status.code() == absl::StatusCode::kCancelled)) {
this->AbortWithError();
}
},
// Hold Arena in activity for GetContext<Arena> usage.
arena_.get());
auto read_loop = 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(
control_endpoint_->Read(frame_header_->GetFrameLength()),
data_endpoint_->Read(frame_header_->message_padding +
frame_header_->message_length));
},
// 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_);
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);
auto stream_id = frame.frame_header.stream_id;
{
MutexLock lock(&mu_);
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();
} else {
return absl::InternalError("Send incoming frames failed.");
}
});
});
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();
}
},
// Hold Arena in activity for GetContext<Arena> usage.
arena_.get());
}
} // namespace chaotic_good

@ -17,29 +17,42 @@
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <initializer_list> // IWYU pragma: keep
#include <map>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/status/status.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 "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/gprpp/sync.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/for_each.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/pipe.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/promise/poll.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_buffer.h"
#include "src/core/lib/transport/metadata_batch.h" // IWYU pragma: keep
#include "src/core/lib/transport/promise_endpoint.h"
@ -58,18 +71,44 @@ class 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 Seq(
// Continuously send data frame with client to server messages.
ForEach(std::move(*call_args.client_to_server_messages),
return TrySeq(
TryJoin(
// 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),
@ -89,33 +128,112 @@ class ClientTransport {
frame.headers = std::move(client_initial_metadata);
initial_frame = false;
}
return Seq(
return TrySeq(
outgoing_frames.Send(ClientFrame(std::move(frame))),
[](bool success) -> absl::Status {
if (!success) {
return absl::InternalError(
"Send frame to outgoing_frames failed.");
// 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));
});
}
private:
// Max buffer is set to 4, so that for stream writes each time it will queue
// at most 2 frames.
MpscReceiver<ClientFrame> outgoing_frames_;
Mutex mu_;
uint32_t next_stream_id_ ABSL_GUARDED_BY(mu_) = 1;
// 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;
// Assigned aligned bytes from setting frame.
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_);
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_;
};

@ -32,6 +32,8 @@
#include "src/core/lib/gprpp/bitset.h"
#include "src/core/lib/gprpp/no_destruct.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_buffer.h"
@ -134,7 +136,9 @@ absl::StatusOr<Arena::PoolPtr<Metadata>> ReadMetadata(
absl::BitGenRef bitsrc) {
if (!maybe_slices.ok()) return maybe_slices.status();
auto& slices = *maybe_slices;
Arena::PoolPtr<Metadata> metadata;
auto arena = GetContext<Arena>();
GPR_ASSERT(arena != nullptr);
Arena::PoolPtr<Metadata> metadata = arena->MakePooled<Metadata>(arena);
parser->BeginFrame(
metadata.get(), std::numeric_limits<uint32_t>::max(),
std::numeric_limits<uint32_t>::max(),

@ -97,6 +97,7 @@ struct ServerFragmentFrame final : public FrameInterface {
FrameHeader frame_header;
ServerMetadataHandle headers;
MessageHandle message;
ServerMetadataHandle trailers;
bool operator==(const ServerFragmentFrame& other) const {

@ -229,30 +229,36 @@ static void send_goaway(grpc_chttp2_transport* t, grpc_error_handle error,
#define GRPC_ARG_SETTINGS_TIMEOUT "grpc.http2.settings_timeout"
namespace {
grpc_core::CallTracerInterface* CallTracerIfEnabled(grpc_chttp2_stream* s) {
using TaskHandle = ::grpc_event_engine::experimental::EventEngine::TaskHandle;
grpc_core::CallTracerInterface* CallTracerIfSampled(grpc_chttp2_stream* s) {
if (s->context == nullptr || !grpc_core::IsTraceRecordCallopsEnabled()) {
return nullptr;
}
return static_cast<grpc_core::CallTracerInterface*>(
auto* call_tracer = static_cast<grpc_core::CallTracerInterface*>(
static_cast<grpc_call_context_element*>(
s->context)[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE]
.value);
if (call_tracer == nullptr || !call_tracer->IsSampled()) {
return nullptr;
}
return call_tracer;
}
std::shared_ptr<grpc_core::TcpTracerInterface> TcpTracerIfEnabled(
std::shared_ptr<grpc_core::TcpTracerInterface> TcpTracerIfSampled(
grpc_chttp2_stream* s) {
if (s->context == nullptr || !s->traced ||
!grpc_core::IsTraceRecordCallopsEnabled()) {
if (s->context == nullptr || !grpc_core::IsTraceRecordCallopsEnabled()) {
return nullptr;
}
auto* call_tracer = static_cast<grpc_core::CallTracerInterface*>(
auto* call_attempt_tracer = static_cast<grpc_core::CallTracerInterface*>(
static_cast<grpc_call_context_element*>(
s->context)[GRPC_CONTEXT_CALL_TRACER]
.value);
if (!call_tracer) {
if (call_attempt_tracer == nullptr || !call_attempt_tracer->IsSampled()) {
return nullptr;
}
return call_tracer->StartNewTcpTrace();
return call_attempt_tracer->StartNewTcpTrace();
}
grpc_core::WriteTimestampsCallback g_write_timestamps_callback = nullptr;
@ -497,10 +503,8 @@ static void read_channel_args(grpc_chttp2_transport* t,
if (max_requests_per_read.has_value()) {
t->max_requests_per_read =
grpc_core::Clamp(*max_requests_per_read, 1, 10000);
} else if (grpc_core::IsChttp2BatchRequestsEnabled()) {
t->max_requests_per_read = 32;
} else {
t->max_requests_per_read = std::numeric_limits<size_t>::max();
t->max_requests_per_read = 32;
}
if (channel_args.GetBool(GRPC_ARG_ENABLE_CHANNELZ)
@ -517,8 +521,8 @@ static void read_channel_args(grpc_chttp2_transport* t,
t->ack_pings = channel_args.GetBool("grpc.http2.ack_pings").value_or(true);
t->allow_tarpit = channel_args.GetBool(GRPC_ARG_HTTP_ALLOW_TARPIT)
.value_or(grpc_core::IsTarpitEnabled());
t->allow_tarpit =
channel_args.GetBool(GRPC_ARG_HTTP_ALLOW_TARPIT).value_or(true);
t->min_tarpit_duration_ms =
channel_args
.GetDurationFromIntMillis(GRPC_ARG_HTTP_TARPIT_MIN_DURATION_MS)
@ -800,41 +804,33 @@ static void close_transport_locked(grpc_chttp2_transport* t,
t->closed_with_error = error;
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, absl::Status(),
"close_transport");
if (t->keepalive_ping_timeout_handle !=
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid) {
t->event_engine->Cancel(std::exchange(
t->keepalive_ping_timeout_handle,
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid));
}
if (t->settings_ack_watchdog !=
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid) {
t->event_engine->Cancel(std::exchange(
t->settings_ack_watchdog,
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid));
if (t->keepalive_ping_timeout_handle != TaskHandle::kInvalid) {
t->event_engine->Cancel(std::exchange(t->keepalive_ping_timeout_handle,
TaskHandle::kInvalid));
}
if (t->delayed_ping_timer_handle.has_value()) {
if (t->event_engine->Cancel(*t->delayed_ping_timer_handle)) {
t->delayed_ping_timer_handle.reset();
if (t->settings_ack_watchdog != TaskHandle::kInvalid) {
t->event_engine->Cancel(
std::exchange(t->settings_ack_watchdog, TaskHandle::kInvalid));
}
if (t->delayed_ping_timer_handle != TaskHandle::kInvalid &&
t->event_engine->Cancel(t->delayed_ping_timer_handle)) {
t->delayed_ping_timer_handle = TaskHandle::kInvalid;
}
if (t->next_bdp_ping_timer_handle.has_value()) {
if (t->event_engine->Cancel(*t->next_bdp_ping_timer_handle)) {
t->next_bdp_ping_timer_handle.reset();
}
if (t->next_bdp_ping_timer_handle != TaskHandle::kInvalid &&
t->event_engine->Cancel(t->next_bdp_ping_timer_handle)) {
t->next_bdp_ping_timer_handle = TaskHandle::kInvalid;
}
switch (t->keepalive_state) {
case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING:
if (t->keepalive_ping_timer_handle.has_value()) {
if (t->event_engine->Cancel(*t->keepalive_ping_timer_handle)) {
t->keepalive_ping_timer_handle.reset();
}
if (t->keepalive_ping_timer_handle != TaskHandle::kInvalid &&
t->event_engine->Cancel(t->keepalive_ping_timer_handle)) {
t->keepalive_ping_timer_handle = TaskHandle::kInvalid;
}
break;
case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING:
if (t->keepalive_ping_timer_handle.has_value()) {
if (t->event_engine->Cancel(*t->keepalive_ping_timer_handle)) {
t->keepalive_ping_timer_handle.reset();
}
if (t->keepalive_ping_timer_handle != TaskHandle::kInvalid &&
t->event_engine->Cancel(t->keepalive_ping_timer_handle)) {
t->keepalive_ping_timer_handle = TaskHandle::kInvalid;
}
break;
case GRPC_CHTTP2_KEEPALIVE_STATE_DYING:
@ -1471,8 +1467,8 @@ static void perform_stream_op_locked(void* stream_op,
s->context = op->payload->context;
s->traced = op->is_traced;
s->call_tracer = CallTracerIfEnabled(s);
s->tcp_tracer = TcpTracerIfEnabled(s);
s->call_tracer = CallTracerIfSampled(s);
s->tcp_tracer = TcpTracerIfSampled(s);
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
gpr_log(GPR_INFO,
"perform_stream_op_locked[s=%p; op=%p]: %s; on_complete = %p", s,
@ -1834,8 +1830,8 @@ static void retry_initiate_ping_locked(
grpc_core::RefCountedPtr<grpc_chttp2_transport> t,
GRPC_UNUSED grpc_error_handle error) {
GPR_DEBUG_ASSERT(error.ok());
GPR_ASSERT(t->delayed_ping_timer_handle.has_value());
t->delayed_ping_timer_handle.reset();
GPR_ASSERT(t->delayed_ping_timer_handle != TaskHandle::kInvalid);
t->delayed_ping_timer_handle = TaskHandle::kInvalid;
grpc_chttp2_initiate_write(t.get(),
GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING);
}
@ -2828,7 +2824,6 @@ static void read_action_parse_loop_locked(
}
close_transport_locked(t.get(), error);
t->endpoint_reading = 0;
} else if (t->closed_with_error.ok()) {
keep_reading = true;
// Since we have read a byte, reset the keepalive timer
@ -2857,17 +2852,15 @@ static void read_action_locked(
grpc_error_handle error) {
// got an incoming read, cancel any pending keepalive timers
t->keepalive_incoming_data_wanted = false;
if (t->keepalive_ping_timeout_handle !=
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid) {
if (t->keepalive_ping_timeout_handle != TaskHandle::kInvalid) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_ping_trace) ||
GRPC_TRACE_FLAG_ENABLED(grpc_keepalive_trace)) {
gpr_log(GPR_INFO,
"%s[%p]: Clear keepalive timer because data was received",
t->is_client ? "CLIENT" : "SERVER", t.get());
}
t->event_engine->Cancel(std::exchange(
t->keepalive_ping_timeout_handle,
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid));
t->event_engine->Cancel(
std::exchange(t->keepalive_ping_timeout_handle, TaskHandle::kInvalid));
}
grpc_error_handle err = error;
if (!err.ok()) {
@ -2960,7 +2953,7 @@ static void finish_bdp_ping_locked(
t->flow_control.bdp_estimator()->CompletePing();
grpc_chttp2_act_on_flowctl_action(t->flow_control.PeriodicUpdate(), t.get(),
nullptr);
GPR_ASSERT(!t->next_bdp_ping_timer_handle.has_value());
GPR_ASSERT(t->next_bdp_ping_timer_handle == TaskHandle::kInvalid);
t->next_bdp_ping_timer_handle =
t->event_engine->RunAfter(next_ping - grpc_core::Timestamp::Now(), [t] {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
@ -2980,8 +2973,8 @@ static void next_bdp_ping_timer_expired_locked(
grpc_core::RefCountedPtr<grpc_chttp2_transport> t,
GRPC_UNUSED grpc_error_handle error) {
GPR_DEBUG_ASSERT(error.ok());
GPR_ASSERT(t->next_bdp_ping_timer_handle.has_value());
t->next_bdp_ping_timer_handle.reset();
GPR_ASSERT(t->next_bdp_ping_timer_handle != TaskHandle::kInvalid);
t->next_bdp_ping_timer_handle = TaskHandle::kInvalid;
if (t->flow_control.bdp_estimator()->accumulator() == 0) {
// Block the bdp ping till we receive more data.
t->bdp_ping_blocked = true;
@ -3050,8 +3043,8 @@ static void init_keepalive_ping_locked(
GRPC_UNUSED grpc_error_handle error) {
GPR_DEBUG_ASSERT(error.ok());
GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING);
GPR_ASSERT(t->keepalive_ping_timer_handle.has_value());
t->keepalive_ping_timer_handle.reset();
GPR_ASSERT(t->keepalive_ping_timer_handle != TaskHandle::kInvalid);
t->keepalive_ping_timer_handle = TaskHandle::kInvalid;
if (t->destroying || !t->closed_with_error.ok()) {
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
} else {
@ -3092,7 +3085,7 @@ static void finish_keepalive_ping_locked(
std::string(t->peer_string.as_string_view()).c_str());
}
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING;
GPR_ASSERT(!t->keepalive_ping_timer_handle.has_value());
GPR_ASSERT(t->keepalive_ping_timer_handle == TaskHandle::kInvalid);
t->keepalive_ping_timer_handle =
t->event_engine->RunAfter(t->keepalive_time, [t] {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
@ -3104,8 +3097,8 @@ static void finish_keepalive_ping_locked(
}
static void maybe_reset_keepalive_ping_timer_locked(grpc_chttp2_transport* t) {
if (t->keepalive_ping_timer_handle.has_value()) {
if (t->event_engine->Cancel(*t->keepalive_ping_timer_handle)) {
if (t->keepalive_ping_timer_handle != TaskHandle::kInvalid &&
t->event_engine->Cancel(t->keepalive_ping_timer_handle)) {
// Cancel succeeds, resets the keepalive ping timer. Note that we don't
// need to Ref or Unref here since we still hold the Ref.
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) ||
@ -3113,14 +3106,13 @@ static void maybe_reset_keepalive_ping_timer_locked(grpc_chttp2_transport* t) {
gpr_log(GPR_INFO, "%s: Keepalive ping cancelled. Resetting timer.",
std::string(t->peer_string.as_string_view()).c_str());
}
t->keepalive_ping_timer_handle = t->event_engine->RunAfter(
t->keepalive_time, [t = t->Ref()]() mutable {
t->keepalive_ping_timer_handle =
t->event_engine->RunAfter(t->keepalive_time, [t = t->Ref()]() mutable {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
init_keepalive_ping(std::move(t));
});
}
}
}
//

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

@ -422,24 +422,10 @@ FlowControlAction StreamFlowControl::UpdateAction(FlowControlAction action) {
}
// min_progress_size_ > 0 means we have a reader ready to read.
if (min_progress_size_ > 0) {
if (IsLazierStreamUpdatesEnabled()) {
if (announced_window_delta_ <=
-static_cast<int64_t>(tfc_->sent_init_window()) / 2) {
urgency = FlowControlAction::Urgency::UPDATE_IMMEDIATELY;
}
} else {
// If we're into initial window to receive that data we should wake up
// and send an update.
if (announced_window_delta_ < 0) {
urgency = FlowControlAction::Urgency::UPDATE_IMMEDIATELY;
} else if (announced_window_delta_ == 0 &&
tfc_->queued_init_window() == 0) {
// Special case when initial window size is zero, meaning that
// announced_window_delta cannot become negative (it may already be so
// however).
urgency = FlowControlAction::Urgency::UPDATE_IMMEDIATELY;
}
}
}
action.set_send_stream_update(urgency);
}

@ -126,7 +126,7 @@ grpc_error_handle grpc_chttp2_rst_stream_parser_parse(void* parser,
grpc_core::StatusIntProperty::kHttp2Error,
static_cast<intptr_t>(reason));
}
if (grpc_core::IsPingOnRstStreamEnabled() && !t->is_client &&
if (!t->is_client &&
absl::Bernoulli(t->bitgen, t->ping_on_rst_stream_percent / 100.0)) {
++t->num_pending_induced_frames;
t->ping_callbacks.RequestPing();

@ -475,31 +475,25 @@ void Encoder::EncodeRepeatingSliceValue(const absl::string_view& key,
void TimeoutCompressorImpl::EncodeWith(absl::string_view key,
Timestamp deadline, Encoder* encoder) {
Timeout timeout = Timeout::FromDuration(deadline - Timestamp::Now());
const Timeout timeout = Timeout::FromDuration(deadline - Timestamp::Now());
auto& table = encoder->hpack_table();
for (auto it = previous_timeouts_.begin(); it != previous_timeouts_.end();
++it) {
double ratio = timeout.RatioVersus(it->timeout);
for (size_t i = 0; i < kNumPreviousValues; i++) {
const auto& previous = previous_timeouts_[i];
if (!table.ConvertableToDynamicIndex(previous.index)) continue;
const double ratio = timeout.RatioVersus(previous.timeout);
// If the timeout we're sending is shorter than a previous timeout, but
// within 3% of it, we'll consider sending it.
if (ratio > -3 && ratio <= 0 &&
table.ConvertableToDynamicIndex(it->index)) {
encoder->EmitIndexed(table.DynamicIndex(it->index));
// Put this timeout to the front of the queue - forces common timeouts to
// be considered earlier.
std::swap(*it, *previous_timeouts_.begin());
if (ratio > -3 && ratio <= 0) {
encoder->EmitIndexed(table.DynamicIndex(previous.index));
return;
}
}
// Clean out some expired timeouts.
while (!previous_timeouts_.empty() &&
!table.ConvertableToDynamicIndex(previous_timeouts_.back().index)) {
previous_timeouts_.pop_back();
}
Slice encoded = timeout.Encode();
uint32_t index = encoder->EmitLitHdrWithNonBinaryStringKeyIncIdx(
Slice::FromStaticString(key), std::move(encoded));
previous_timeouts_.push_back(PreviousTimeout{timeout, index});
uint32_t i = next_previous_value_;
++next_previous_value_;
previous_timeouts_[i % kNumPreviousValues] = PreviousTimeout{timeout, index};
}
Encoder::Encoder(HPackCompressor* compressor, bool use_true_binary_metadata,

@ -276,8 +276,10 @@ class Compressor<MetadataTrait, SmallSetOfValuesCompressor> {
};
struct PreviousTimeout {
Timeout timeout;
uint32_t index;
Timeout timeout = Timeout::FromDuration(Duration::Zero());
// Dynamic table index of a previously sent timeout
// 0 is guaranteed not in the dynamic table so is a safe initializer
uint32_t index = 0;
};
class TimeoutCompressorImpl {
@ -285,7 +287,9 @@ class TimeoutCompressorImpl {
void EncodeWith(absl::string_view key, Timestamp deadline, Encoder* encoder);
private:
std::vector<PreviousTimeout> previous_timeouts_;
static constexpr const size_t kNumPreviousValues = 5;
PreviousTimeout previous_timeouts_[kNumPreviousValues];
uint32_t next_previous_value_ = 0;
};
template <typename MetadataTrait>

@ -21,8 +21,7 @@
#include <stdint.h>
#include <limits>
#include "absl/container/inlined_vector.h"
#include <vector>
#include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
@ -59,6 +58,7 @@ class HPackEncoderTable {
table_elems_ - index;
}
// Check if an element index is convertable to a dynamic index
// Note that 0 is always not convertable
bool ConvertableToDynamicIndex(uint32_t index) const {
return index > tail_remote_index_;
}
@ -73,8 +73,7 @@ class HPackEncoderTable {
uint32_t table_elems_ = 0;
uint32_t table_size_ = 0;
// The size of each element in the HPACK table.
absl::InlinedVector<EntrySize, hpack_constants::kInitialTableEntries>
elem_size_;
std::vector<EntrySize> elem_size_;
};
} // namespace grpc_core

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

Loading…
Cancel
Save