grpc 1.82.0 → 1.83.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/etc/roots.pem +10400 -3855
  4. data/include/grpc/grpc_audit_logging.h +2 -2
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +23 -0
  7. data/src/core/call/call_filters.h +19 -3
  8. data/src/core/call/call_spine.h +4 -4
  9. data/src/core/call/client_call.cc +1 -1
  10. data/src/core/call/metadata.cc +7 -2
  11. data/src/core/call/server_call.cc +13 -3
  12. data/src/core/call/server_call.h +5 -3
  13. data/src/core/client_channel/backup_poller.cc +2 -17
  14. data/src/core/client_channel/client_channel.cc +17 -14
  15. data/src/core/client_channel/client_channel.h +3 -1
  16. data/src/core/client_channel/client_channel_filter.cc +11 -13
  17. data/src/core/client_channel/client_channel_service_config.cc +5 -13
  18. data/src/core/client_channel/direct_channel.cc +5 -1
  19. data/src/core/client_channel/direct_channel.h +3 -1
  20. data/src/core/config/experiment_env_var.cc +30 -0
  21. data/src/core/config/experiment_env_var.h +26 -0
  22. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
  23. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
  24. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
  25. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
  26. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
  27. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
  28. data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
  29. data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
  30. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
  31. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
  32. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
  33. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
  34. data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
  35. data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
  36. data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
  37. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
  38. data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
  39. data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
  40. data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
  41. data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
  42. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
  43. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
  44. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
  45. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
  46. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
  47. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
  48. data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
  49. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
  50. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
  51. data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
  52. data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  54. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
  55. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
  56. data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
  57. data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
  58. data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
  59. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
  60. data/src/core/handshaker/security/secure_endpoint.cc +0 -13
  61. data/src/core/lib/channel/promise_based_filter.cc +77 -3
  62. data/src/core/lib/channel/promise_based_filter.h +238 -184
  63. data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
  64. data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
  65. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
  66. data/src/core/lib/event_engine/shim.cc +2 -16
  67. data/src/core/lib/event_engine/shim.h +0 -4
  68. data/src/core/lib/experiments/experiments.cc +51 -102
  69. data/src/core/lib/experiments/experiments.h +37 -59
  70. data/src/core/lib/iomgr/error.cc +3 -73
  71. data/src/core/lib/iomgr/error.h +8 -6
  72. data/src/core/lib/iomgr/error_cfstream.cc +1 -2
  73. data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
  74. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
  75. data/src/core/lib/iomgr/tcp_posix.cc +2 -6
  76. data/src/core/lib/security/authorization/audit_logging.cc +2 -2
  77. data/src/core/lib/security/authorization/audit_logging.h +3 -3
  78. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
  79. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  80. data/src/core/lib/security/authorization/matchers.cc +20 -20
  81. data/src/core/lib/security/authorization/matchers.h +15 -16
  82. data/src/core/lib/security/authorization/rbac_policy.h +1 -1
  83. data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
  84. data/src/core/lib/security/authorization/stdout_logger.h +6 -5
  85. data/src/core/lib/surface/call.cc +0 -8
  86. data/src/core/lib/surface/call.h +2 -0
  87. data/src/core/lib/surface/channel.cc +21 -2
  88. data/src/core/lib/surface/channel.h +14 -6
  89. data/src/core/lib/surface/filter_stack_call.cc +10 -29
  90. data/src/core/lib/surface/legacy_channel.cc +7 -7
  91. data/src/core/lib/surface/legacy_channel.h +3 -1
  92. data/src/core/lib/surface/version.cc +2 -2
  93. data/src/core/lib/transport/bdp_estimator.cc +13 -13
  94. data/src/core/lib/transport/bdp_estimator.h +9 -5
  95. data/src/core/lib/transport/error_utils.cc +26 -138
  96. data/src/core/lib/transport/promise_endpoint.h +2 -4
  97. data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
  98. data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
  99. data/src/core/load_balancing/pick_first/pick_first.h +6 -0
  100. data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
  101. data/src/core/load_balancing/rls/rls.cc +2 -1
  102. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
  103. data/src/core/load_balancing/xds/cds.cc +80 -56
  104. data/src/core/load_balancing/xds/cds.h +21 -0
  105. data/src/core/mitigation_engine/mitigation.h +53 -0
  106. data/src/core/mitigation_engine/mitigation_provider.h +62 -0
  107. data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
  108. data/src/core/resolver/xds/xds_resolver.cc +14 -11
  109. data/src/core/server/server.h +1 -4
  110. data/src/core/server/server_config_selector.h +5 -4
  111. data/src/core/server/server_config_selector_filter.cc +67 -80
  112. data/src/core/server/xds_server_config_fetcher.cc +681 -692
  113. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
  114. data/src/core/telemetry/call_tracer.cc +49 -2
  115. data/src/core/telemetry/call_tracer.h +1 -0
  116. data/src/core/telemetry/tcp_tracer.h +38 -0
  117. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  118. data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
  119. data/src/core/tsi/ssl_telemetry_utils.h +74 -0
  120. data/src/core/tsi/ssl_transport_security.cc +577 -301
  121. data/src/core/tsi/ssl_transport_security.h +22 -6
  122. data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
  123. data/src/core/tsi/transport_security.h +7 -0
  124. data/src/core/util/http_client/httpcli.cc +1 -4
  125. data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
  126. data/src/core/util/status_helper.cc +71 -192
  127. data/src/core/util/status_helper.h +16 -21
  128. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
  129. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
  130. data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
  131. data/src/core/xds/grpc/xds_common_types.cc +94 -38
  132. data/src/core/xds/grpc/xds_common_types.h +33 -18
  133. data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
  134. data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
  135. data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
  136. data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
  137. data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
  138. data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
  139. data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
  140. data/src/core/xds/grpc/xds_routing.cc +113 -82
  141. data/src/core/xds/grpc/xds_routing.h +70 -20
  142. data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
  143. data/src/core/xds/grpc/xds_server_grpc.h +16 -2
  144. data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
  145. data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
  146. data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
  147. data/src/core/xds/xds_client/lrs_client.cc +3 -7
  148. data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
  149. data/src/core/xds/xds_client/xds_client.cc +2 -15
  150. data/src/core/xds/xds_client/xds_transport.h +3 -0
  151. data/src/ruby/lib/grpc/version.rb +1 -1
  152. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
  153. metadata +9 -1
@@ -0,0 +1,62 @@
1
+ //
2
+ //
3
+ // Copyright 2026 gRPC authors.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //
18
+
19
+ #ifndef GRPC_SRC_CORE_MITIGATION_ENGINE_MITIGATION_PROVIDER_H
20
+ #define GRPC_SRC_CORE_MITIGATION_ENGINE_MITIGATION_PROVIDER_H
21
+
22
+ #include <cstdint>
23
+ #include <vector>
24
+
25
+ #include "src/core/mitigation_engine/mitigation.h"
26
+ #include "src/core/util/ref_counted_ptr.h"
27
+ #include "absl/functional/any_invocable.h"
28
+
29
+ namespace grpc_core {
30
+
31
+ // Opaque handle for unsubscription.
32
+ struct MitigationSubscriptionHandle {
33
+ uintptr_t id = 0;
34
+ bool operator==(const MitigationSubscriptionHandle& other) const = default;
35
+ };
36
+
37
+ class MitigationProvider {
38
+ public:
39
+ virtual ~MitigationProvider() = default;
40
+
41
+ // Subscribes to mitigation configuration updates.
42
+ //
43
+ // The provided callback is invoked whenever the mitigation rules change.
44
+ //
45
+ // Returns an opaque MitigationSubscriptionHandle to be used as an
46
+ // unsubscription token for CancelWatch().
47
+ //
48
+ // Mitigations are passed as RefCountedPtrs to enable efficient shared
49
+ // ownership of the read-only rules among all listeners, avoiding costly
50
+ // deep copies during config updates.
51
+ virtual MitigationSubscriptionHandle ListenForMitigations(
52
+ absl::AnyInvocable<void(std::vector<RefCountedPtr<Mitigation>>)>
53
+ new_mitigations) = 0;
54
+
55
+ // Unsubscribes a previously registered callback using its original
56
+ // MitigationSubscriptionHandle token.
57
+ virtual void CancelWatch(MitigationSubscriptionHandle handle) = 0;
58
+ };
59
+
60
+ } // namespace grpc_core
61
+
62
+ #endif // GRPC_SRC_CORE_MITIGATION_ENGINE_MITIGATION_PROVIDER_H
@@ -36,12 +36,7 @@ void RegisterDnsResolver(CoreConfiguration::Builder* builder) {
36
36
  std::make_unique<EventEngineClientChannelDNSResolverFactory>());
37
37
  return;
38
38
  #endif
39
- #ifdef GRPC_PYTHON_BUILD
40
- bool use_ee = IsEventEnginePollerForPythonEnabled();
41
- #else // GRPC_PYTHON_BUILD
42
- bool use_ee = true;
43
- #endif // GRPC_PYTHON_BUILD
44
- if (use_ee && IsEventEngineDnsEnabled()) {
39
+ if (IsEventEngineDnsEnabled()) {
45
40
  VLOG(2) << "Using EventEngine dns resolver";
46
41
  builder->resolver_registry()->RegisterResolverFactory(
47
42
  std::make_unique<EventEngineClientChannelDNSResolverFactory>());
@@ -423,12 +423,14 @@ void XdsResolver::RouteConfigData::BuildFilterChains(
423
423
  FilterChainBuilder& builder, Blackboard& blackboard) {
424
424
  const auto& hcm = std::get<XdsListenerResource::HttpConnectionManager>(
425
425
  xds_config.listener->listener);
426
- XdsRouting::PerRouteFilterChainBuilder per_route_builder(
427
- hcm.http_filters, http_filter_registry, *xds_config.virtual_host, builder,
426
+ XdsRouting::RouteConfigFilterChainBuilder route_config_builder(
427
+ hcm.http_filters, http_filter_registry, builder,
428
428
  [](FilterChainBuilder& builder) {
429
429
  builder.AddFilter<ClusterSelectionFilter>(nullptr);
430
430
  },
431
431
  blackboard);
432
+ auto vhost_builder = route_config_builder.MakeVirtualHostFilterChainBuilder(
433
+ *xds_config.virtual_host);
432
434
  // Set the filter chain for each route.
433
435
  for (auto& route_entry : routes_) {
434
436
  const auto* route_action =
@@ -441,20 +443,21 @@ void XdsResolver::RouteConfigData::BuildFilterChains(
441
443
  XdsRouteConfigResource::Route::RouteAction::ClusterWeight>>(
442
444
  &route_action->action);
443
445
  weighted_clusters != nullptr) {
444
- per_route_builder.BuildFilterChainForRouteWithWeightedClusters(
445
- route_entry.route,
446
- [&](size_t index,
447
- absl::StatusOr<RefCountedPtr<const FilterChain>> filter_chain) {
448
- GRPC_CHECK_LT(index, route_entry.weighted_cluster_state.size());
449
- route_entry.weighted_cluster_state[index].filter_chain =
450
- std::move(filter_chain);
451
- });
446
+ auto weighted_cluster_builder =
447
+ vhost_builder.MakeWeightedClusterRouteFilterChainBuilder(
448
+ route_entry.route);
449
+ for (size_t i = 0; i < weighted_clusters->size(); ++i) {
450
+ GRPC_CHECK_LT(i, route_entry.weighted_cluster_state.size());
451
+ route_entry.weighted_cluster_state[i].filter_chain =
452
+ weighted_cluster_builder.BuildFilterChainForClusterWeight(
453
+ (*weighted_clusters)[i]);
454
+ }
452
455
  }
453
456
  // If the route does not use WeightedClusters, then we generate a
454
457
  // filter chain for the route.
455
458
  else {
456
459
  route_entry.filter_chain =
457
- per_route_builder.BuildFilterChainForRoute(route_entry.route);
460
+ vhost_builder.BuildFilterChainForRoute(route_entry.route);
458
461
  }
459
462
  }
460
463
  }
@@ -73,9 +73,6 @@
73
73
  #include "absl/status/statusor.h"
74
74
  #include "absl/strings/string_view.h"
75
75
 
76
- #define GRPC_ARG_SERVER_MAX_PENDING_REQUESTS "grpc.server.max_pending_requests"
77
- #define GRPC_ARG_SERVER_MAX_PENDING_REQUESTS_HARD_LIMIT \
78
- "grpc.server.max_pending_requests_hard_limit"
79
76
  #define GRPC_ARG_SERVER_INTERNAL_PARENT_CALL_ARENA \
80
77
  "grpc.internal.parent_call_arena"
81
78
 
@@ -100,7 +97,7 @@ class ServerConfigFetcher
100
97
  virtual void UpdateConnectionManager(
101
98
  RefCountedPtr<ConnectionManager> manager) = 0;
102
99
  // Implementations should stop serving when this is called. Serving should
103
- // only resume when UpdateConfig() is invoked.
100
+ // only resume when UpdateConnectionManager() is invoked.
104
101
  virtual void StopServing() = 0;
105
102
  };
106
103
 
@@ -62,11 +62,12 @@ class ServerConfigSelectorProvider
62
62
  absl::StatusOr<RefCountedPtr<ServerConfigSelector>> update) = 0;
63
63
  };
64
64
 
65
- ~ServerConfigSelectorProvider() override = default;
66
- // Only a single watcher is allowed at present
65
+ // TODO(roth): Change this to return void after removing
66
+ // xds_server_filter_chain_per_route experiment.
67
67
  virtual absl::StatusOr<RefCountedPtr<ServerConfigSelector>> Watch(
68
- std::unique_ptr<ServerConfigSelectorWatcher> watcher) = 0;
69
- virtual void CancelWatch() = 0;
68
+ std::shared_ptr<ServerConfigSelectorWatcher> watcher) = 0;
69
+ virtual void CancelWatch(
70
+ std::shared_ptr<ServerConfigSelectorWatcher> watcher) = 0;
70
71
 
71
72
  static absl::string_view ChannelArgName() {
72
73
  return "grpc.internal.server_config_selector_provider";
@@ -27,6 +27,7 @@
27
27
  #include "src/core/lib/event_engine/event_engine_context.h"
28
28
  #include "src/core/lib/promise/arena_promise.h"
29
29
  #include "src/core/lib/promise/context.h"
30
+ #include "src/core/lib/promise/observable.h"
30
31
  #include "src/core/lib/promise/promise.h"
31
32
  #include "src/core/lib/resource_quota/arena.h"
32
33
  #include "src/core/lib/transport/transport.h"
@@ -37,7 +38,6 @@
37
38
  #include "src/core/util/latent_see.h"
38
39
  #include "src/core/util/ref_counted_ptr.h"
39
40
  #include "src/core/util/status_helper.h"
40
- #include "src/core/util/sync.h"
41
41
  #include "absl/base/thread_annotations.h"
42
42
  #include "absl/status/status.h"
43
43
  #include "absl/status/statusor.h"
@@ -103,6 +103,7 @@ class LegacyServerConfigSelectorFilter final
103
103
  };
104
104
 
105
105
  RefCountedPtr<ServerConfigSelectorProvider> server_config_selector_provider_;
106
+ std::shared_ptr<ServerConfigSelectorWatcher> watcher_;
106
107
  Mutex mu_;
107
108
  std::optional<absl::StatusOr<RefCountedPtr<ServerConfigSelector>>>
108
109
  config_selector_ ABSL_GUARDED_BY(mu_);
@@ -125,10 +126,8 @@ LegacyServerConfigSelectorFilter::LegacyServerConfigSelectorFilter(
125
126
  : server_config_selector_provider_(
126
127
  std::move(server_config_selector_provider)) {
127
128
  GRPC_CHECK(server_config_selector_provider_ != nullptr);
128
- auto server_config_selector_watcher =
129
- std::make_unique<ServerConfigSelectorWatcher>(Ref());
130
- auto config_selector = server_config_selector_provider_->Watch(
131
- std::move(server_config_selector_watcher));
129
+ watcher_ = std::make_shared<ServerConfigSelectorWatcher>(Ref());
130
+ auto config_selector = server_config_selector_provider_->Watch(watcher_);
132
131
  MutexLock lock(&mu_);
133
132
  // It's possible for the watcher to have already updated config_selector_
134
133
  if (!config_selector_.has_value()) {
@@ -138,7 +137,7 @@ LegacyServerConfigSelectorFilter::LegacyServerConfigSelectorFilter(
138
137
 
139
138
  void LegacyServerConfigSelectorFilter::Orphan() {
140
139
  if (server_config_selector_provider_ != nullptr) {
141
- server_config_selector_provider_->CancelWatch();
140
+ server_config_selector_provider_->CancelWatch(std::move(watcher_));
142
141
  }
143
142
  Unref();
144
143
  }
@@ -172,27 +171,10 @@ class ServerConfigSelectorFilter final
172
171
  : public ImplementChannelFilter<ServerConfigSelectorFilter>,
173
172
  public InternallyRefCounted<ServerConfigSelectorFilter> {
174
173
  public:
175
- explicit ServerConfigSelectorFilter(
176
- RefCountedPtr<ServerConfigSelectorProvider>
177
- server_config_selector_provider);
178
-
179
- static absl::string_view TypeName() {
180
- return "server_config_selector_filter";
181
- }
182
-
183
- ServerConfigSelectorFilter(const ServerConfigSelectorFilter&) = delete;
184
- ServerConfigSelectorFilter& operator=(const ServerConfigSelectorFilter&) =
185
- delete;
186
-
187
- static absl::StatusOr<OrphanablePtr<ServerConfigSelectorFilter>> Create(
188
- const ChannelArgs& args, ChannelFilter::Args);
189
-
190
- void Orphan() override;
191
-
192
174
  class Call {
193
175
  public:
194
- absl::Status OnClientInitialMetadata(ClientMetadata& md,
195
- ServerConfigSelectorFilter* filter);
176
+ ArenaPromise<absl::Status> OnClientInitialMetadata(
177
+ ClientMetadata& md, ServerConfigSelectorFilter* filter);
196
178
  static inline const NoInterceptor OnServerInitialMetadata;
197
179
  static inline const NoInterceptor OnServerTrailingMetadata;
198
180
  static inline const NoInterceptor OnClientToServerMessage;
@@ -201,9 +183,42 @@ class ServerConfigSelectorFilter final
201
183
  static inline const NoInterceptor OnFinalize;
202
184
  };
203
185
 
204
- absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector() {
205
- MutexLock lock(&mu_);
206
- return config_selector_.value();
186
+ static absl::StatusOr<OrphanablePtr<ServerConfigSelectorFilter>> Create(
187
+ const ChannelArgs& args, ChannelFilter::Args) {
188
+ auto server_config_selector_provider =
189
+ args.GetObjectRef<ServerConfigSelectorProvider>();
190
+ if (server_config_selector_provider == nullptr) {
191
+ return absl::UnknownError("No ServerConfigSelectorProvider object found");
192
+ }
193
+ return MakeOrphanable<ServerConfigSelectorFilter>(
194
+ std::move(server_config_selector_provider));
195
+ }
196
+
197
+ explicit ServerConfigSelectorFilter(
198
+ RefCountedPtr<ServerConfigSelectorProvider>
199
+ server_config_selector_provider)
200
+ : server_config_selector_provider_(
201
+ std::move(server_config_selector_provider)),
202
+ config_selector_(nullptr) {
203
+ watcher_ = std::make_shared<ServerConfigSelectorWatcher>(Ref());
204
+ // TODO(roth): Remove the void cast when removing the
205
+ // xds_server_filter_chain_per_route experiment.
206
+ (void)server_config_selector_provider_->Watch(watcher_);
207
+ }
208
+
209
+ ServerConfigSelectorFilter(const ServerConfigSelectorFilter&) = delete;
210
+ ServerConfigSelectorFilter& operator=(const ServerConfigSelectorFilter&) =
211
+ delete;
212
+
213
+ void Orphan() override {
214
+ if (server_config_selector_provider_ != nullptr) {
215
+ server_config_selector_provider_->CancelWatch(std::move(watcher_));
216
+ }
217
+ Unref();
218
+ }
219
+
220
+ static absl::string_view TypeName() {
221
+ return "server_config_selector_filter";
207
222
  }
208
223
 
209
224
  private:
@@ -215,8 +230,8 @@ class ServerConfigSelectorFilter final
215
230
  : filter_(filter) {}
216
231
  void OnServerConfigSelectorUpdate(
217
232
  absl::StatusOr<RefCountedPtr<ServerConfigSelector>> update) override {
218
- MutexLock lock(&filter_->mu_);
219
- filter_->config_selector_ = std::move(update);
233
+ // TODO(roth): Build filter chains here.
234
+ filter_->config_selector_.Set(std::move(update));
220
235
  }
221
236
 
222
237
  private:
@@ -224,61 +239,33 @@ class ServerConfigSelectorFilter final
224
239
  };
225
240
 
226
241
  RefCountedPtr<ServerConfigSelectorProvider> server_config_selector_provider_;
227
- Mutex mu_;
228
- std::optional<absl::StatusOr<RefCountedPtr<ServerConfigSelector>>>
229
- config_selector_ ABSL_GUARDED_BY(mu_);
242
+ std::shared_ptr<ServerConfigSelectorWatcher> watcher_;
243
+ Observable<absl::StatusOr<RefCountedPtr<ServerConfigSelector>>>
244
+ config_selector_;
230
245
  };
231
246
 
232
- absl::StatusOr<OrphanablePtr<ServerConfigSelectorFilter>>
233
- ServerConfigSelectorFilter::Create(const ChannelArgs& args,
234
- ChannelFilter::Args) {
235
- ServerConfigSelectorProvider* server_config_selector_provider =
236
- args.GetObject<ServerConfigSelectorProvider>();
237
- if (server_config_selector_provider == nullptr) {
238
- return absl::UnknownError("No ServerConfigSelectorProvider object found");
239
- }
240
- return MakeOrphanable<ServerConfigSelectorFilter>(
241
- server_config_selector_provider->Ref());
242
- }
243
-
244
- ServerConfigSelectorFilter::ServerConfigSelectorFilter(
245
- RefCountedPtr<ServerConfigSelectorProvider> server_config_selector_provider)
246
- : server_config_selector_provider_(
247
- std::move(server_config_selector_provider)) {
248
- GRPC_CHECK(server_config_selector_provider_ != nullptr);
249
- auto server_config_selector_watcher =
250
- std::make_unique<ServerConfigSelectorWatcher>(Ref());
251
- auto config_selector = server_config_selector_provider_->Watch(
252
- std::move(server_config_selector_watcher));
253
- MutexLock lock(&mu_);
254
- // It's possible for the watcher to have already updated config_selector_
255
- if (!config_selector_.has_value()) {
256
- config_selector_ = std::move(config_selector);
257
- }
258
- }
259
-
260
- void ServerConfigSelectorFilter::Orphan() {
261
- if (server_config_selector_provider_ != nullptr) {
262
- server_config_selector_provider_->CancelWatch();
263
- }
264
- Unref();
265
- }
266
-
267
- absl::Status ServerConfigSelectorFilter::Call::OnClientInitialMetadata(
247
+ ArenaPromise<absl::Status>
248
+ ServerConfigSelectorFilter::Call::OnClientInitialMetadata(
268
249
  ClientMetadata& md, ServerConfigSelectorFilter* filter) {
269
250
  GRPC_LATENT_SEE_SCOPE(
270
251
  "ServerConfigSelectorFilter::Call::OnClientInitialMetadata");
271
- auto sel = filter->config_selector();
272
- if (!sel.ok()) return sel.status();
273
- auto call_config = sel.value()->GetCallConfig(&md);
274
- if (!call_config.ok()) {
275
- return absl::UnavailableError(StatusToString(call_config.status()));
276
- }
277
- auto* service_config_call_data =
278
- GetContext<Arena>()->New<ServiceConfigCallData>(GetContext<Arena>());
279
- service_config_call_data->SetServiceConfig(
280
- std::move(call_config->service_config), call_config->method_configs);
281
- return absl::OkStatus();
252
+ return TrySeq(
253
+ filter->config_selector_.Next(nullptr),
254
+ [&md](
255
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector) {
256
+ if (!config_selector.ok()) return config_selector.status();
257
+ auto call_config = (*config_selector)->GetCallConfig(&md);
258
+ if (!call_config.ok()) {
259
+ return absl::UnavailableError(StatusToString(call_config.status()));
260
+ }
261
+ auto* arena = GetContext<Arena>();
262
+ auto* service_config_call_data =
263
+ arena->New<ServiceConfigCallData>(arena);
264
+ service_config_call_data->SetServiceConfig(
265
+ std::move(call_config->service_config),
266
+ call_config->method_configs);
267
+ return absl::OkStatus();
268
+ });
282
269
  }
283
270
 
284
271
  } // namespace