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
@@ -78,11 +78,11 @@ class AuditLoggerFactory {
78
78
  virtual ~AuditLoggerFactory() = default;
79
79
  virtual absl::string_view name() const = 0;
80
80
 
81
- virtual absl::StatusOr<std::unique_ptr<Config>> ParseAuditLoggerConfig(
81
+ virtual absl::StatusOr<std::shared_ptr<const Config>> ParseAuditLoggerConfig(
82
82
  const Json& json) = 0;
83
83
 
84
84
  virtual std::unique_ptr<AuditLogger> CreateAuditLogger(
85
- std::unique_ptr<AuditLoggerFactory::Config>) = 0;
85
+ std::shared_ptr<const Config> config) = 0;
86
86
  };
87
87
 
88
88
  // Registers an audit logger factory. This should only be called during
@@ -155,6 +155,8 @@ typedef enum {
155
155
  GRPC_TLS_GROUP_X25519,
156
156
  /** X25519_MLKEM768 hybrid key exchange. Post-quantum cryptography. */
157
157
  GRPC_TLS_GROUP_X25519_MLKEM768,
158
+ /** secp384r1 ECDH key exchange. */
159
+ GRPC_TLS_GROUP_SECP384R1,
158
160
  } grpc_tls_key_exchange_group;
159
161
 
160
162
  #ifdef __cplusplus
@@ -120,6 +120,22 @@
120
120
  before the request is cancelled */
121
121
  #define GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS \
122
122
  "grpc.server_max_unrequested_time_in_server"
123
+ /** The soft limit on the number of pending requests in the server. Int valued.
124
+ * If the number of pending queued requests exceeds this soft limit, then the
125
+ * server will start to probabilistically reject new incoming requests up until
126
+ * the hard limit. Defaults to 1000.
127
+ * Note: It is not recommended to change this value unless the operational
128
+ * implications are fully understood.
129
+ */
130
+ #define GRPC_ARG_SERVER_MAX_PENDING_REQUESTS "grpc.server.max_pending_requests"
131
+ /** The hard limit on the number of pending requests in the server. Int valued.
132
+ * If the number of pending queued requests reaches this hard limit, all new
133
+ * incoming requests will be rejected. Defaults to 3000.
134
+ * Note: It is not recommended to change this value unless the operational
135
+ * implications are fully understood.
136
+ */
137
+ #define GRPC_ARG_SERVER_MAX_PENDING_REQUESTS_HARD_LIMIT \
138
+ "grpc.server.max_pending_requests_hard_limit"
123
139
  /** Channel arg to override the http2 :scheme header. String valued. */
124
140
  #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
125
141
  /** How many pings can the client send before needing to send a data/header
@@ -441,7 +457,14 @@
441
457
  /** \} */
442
458
  /** If non-zero, enable TCP tracing and stats collection. */
443
459
  #define GRPC_ARG_TCP_TRACING_ENABLED "grpc.tcp_tracing_enabled"
460
+ /* Enable tracing full buffer payloads for TCP telemetry. */
461
+ #define GRPC_ARG_TCP_TRACE_FULL_BUFFER "grpc.experimental.tcp_trace_full_buffer"
444
462
  /** Server config fetcher. */
445
463
  #define GRPC_ARG_SERVER_CONFIG_FETCHER "grpc.server_config_fetcher"
464
+ /** Set the maximum size of a security frame that can be received on a HTTP2
465
+ * Connection. Check file core/ext/transport/chttp2/transport/frame.cc for
466
+ * details on the Security Frame.
467
+ */
468
+ #define GRPC_ARG_MAX_SECURITY_FRAME_SIZE "grpc.http2.max_security_frame_size"
446
469
 
447
470
  #endif /* GRPC_IMPL_CHANNEL_ARG_NAMES_H */
@@ -1976,7 +1976,11 @@ class CallFilters {
1976
1976
  // Returns a promise that resolves to a StatusFlag indicating success
1977
1977
  StatusFlag PushServerInitialMetadata(ServerMetadataHandle md) {
1978
1978
  push_server_initial_metadata_ = std::move(md);
1979
- return call_state_.PushServerInitialMetadata();
1979
+ auto flag = call_state_.PushServerInitialMetadata();
1980
+ if (!IsStatusOk(flag)) {
1981
+ push_server_initial_metadata_ = nullptr;
1982
+ }
1983
+ return flag;
1980
1984
  }
1981
1985
  // Client: Fetch server initial metadata
1982
1986
  // Returns a promise that resolves to ValueOrFailure<ServerMetadataHandle>
@@ -2015,7 +2019,13 @@ class CallFilters {
2015
2019
  GRPC_DCHECK_NE(message.get(), nullptr);
2016
2020
  GRPC_DCHECK_EQ(push_client_to_server_message_.get(), nullptr);
2017
2021
  push_client_to_server_message_ = std::move(message);
2018
- return [this]() { return call_state_.PollPushClientToServerMessage(); };
2022
+ return Map([this]() { return call_state_.PollPushClientToServerMessage(); },
2023
+ [this](StatusFlag r) {
2024
+ if (!IsStatusOk(r)) {
2025
+ push_client_to_server_message_ = nullptr;
2026
+ }
2027
+ return r;
2028
+ });
2019
2029
  }
2020
2030
  // Client: Indicate that no more messages will be sent
2021
2031
  void FinishClientToServerSends() { call_state_.ClientToServerHalfClose(); }
@@ -2047,7 +2057,13 @@ class CallFilters {
2047
2057
  GRPC_MUST_USE_RESULT auto PushServerToClientMessage(MessageHandle message) {
2048
2058
  call_state_.BeginPushServerToClientMessage();
2049
2059
  push_server_to_client_message_ = std::move(message);
2050
- return [this]() { return call_state_.PollPushServerToClientMessage(); };
2060
+ return Map([this]() { return call_state_.PollPushServerToClientMessage(); },
2061
+ [this](StatusFlag r) {
2062
+ if (!IsStatusOk(r)) {
2063
+ push_server_to_client_message_ = nullptr;
2064
+ }
2065
+ return r;
2066
+ });
2051
2067
  }
2052
2068
  // Server: Fetch server to client message
2053
2069
  // Returns a promise that resolves to ServerToClientNextMessage
@@ -33,6 +33,7 @@
33
33
  #include "src/core/lib/promise/pipe.h"
34
34
  #include "src/core/lib/promise/prioritized_race.h"
35
35
  #include "src/core/lib/promise/promise.h"
36
+ #include "src/core/lib/promise/race.h"
36
37
  #include "src/core/lib/promise/status_flag.h"
37
38
  #include "src/core/lib/promise/try_seq.h"
38
39
  #include "src/core/util/dual_ref_counted.h"
@@ -223,10 +224,9 @@ class CallSpine final : public Party, public channelz::DataSource {
223
224
  template <typename Promise>
224
225
  auto UntilCallCompletes(Promise&& promise) {
225
226
  using Result = PromiseResult<std::decay_t<Promise>>;
226
- return PrioritizedRace(std::forward<Promise>(promise),
227
- Map(WasCancelled(), [](bool) {
228
- return FailureStatusCast<Result>(Failure{});
229
- }));
227
+ return Race(Map(WasCancelled(),
228
+ [](bool) { return FailureStatusCast<Result>(Failure{}); }),
229
+ std::forward<Promise>(promise));
230
230
  }
231
231
 
232
232
  template <typename PromiseFactory>
@@ -443,7 +443,7 @@ void ClientCall::OnReceivedStatus(ServerMetadataHandle server_trailing_metadata,
443
443
  .value_or(GRPC_STATUS_UNKNOWN);
444
444
  *out_status = status;
445
445
  Slice message_slice;
446
- if (!IsErrorFlattenEnabled() || status != GRPC_STATUS_OK) {
446
+ if (status != GRPC_STATUS_OK) {
447
447
  if (Slice* message =
448
448
  server_trailing_metadata->get_pointer(GrpcMessageMetadata())) {
449
449
  message_slice = message->Ref();
@@ -37,10 +37,15 @@ ServerMetadataHandle ServerMetadataFromStatus(const absl::Status& status) {
37
37
  absl::Status ServerMetadataToStatus(ServerMetadata& md) {
38
38
  const auto grpc_status =
39
39
  md.get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN);
40
+ if (grpc_status == GRPC_STATUS_OK) {
41
+ return absl::OkStatus();
42
+ }
40
43
  const auto* error_slice = md.get_pointer(GrpcMessageMetadata());
44
+ absl::string_view message = error_slice != nullptr
45
+ ? error_slice->as_string_view()
46
+ : absl::string_view();
41
47
  return grpc_error_set_int(
42
- absl::Status(static_cast<absl::StatusCode>(grpc_status),
43
- error_slice->as_string_view()),
48
+ absl::Status(static_cast<absl::StatusCode>(grpc_status), message),
44
49
  StatusIntProperty::kRpcStatus, grpc_status);
45
50
  }
46
51
 
@@ -101,6 +101,18 @@ grpc_call_error ValidateServerBatch(const grpc_op* ops, size_t nops) {
101
101
 
102
102
  } // namespace
103
103
 
104
+ absl::string_view ServerCall::GetServerAuthority() const {
105
+ GRPC_DCHECK(client_initial_metadata_stored_ != nullptr);
106
+ if (client_initial_metadata_stored_ != nullptr) {
107
+ const Slice* authority_metadata =
108
+ client_initial_metadata_stored_->get_pointer(HttpAuthorityMetadata());
109
+ if (authority_metadata != nullptr) {
110
+ return authority_metadata->as_string_view();
111
+ }
112
+ }
113
+ return "";
114
+ }
115
+
104
116
  grpc_call_error ServerCall::StartBatch(const grpc_op* ops, size_t nops,
105
117
  void* notify_tag,
106
118
  bool is_notify_tag_closure) {
@@ -246,15 +258,13 @@ grpc_call* MakeServerCall(CallHandler call_handler,
246
258
  ServerInterface* server, grpc_completion_queue* cq,
247
259
  grpc_metadata_array* publish_initial_metadata,
248
260
  RefCountedPtr<Arena> parent_arena) {
249
- PublishMetadataArray(client_initial_metadata.get(), publish_initial_metadata,
250
- false);
251
261
  // TODO(ctiller): ideally we'd put this in the arena with the CallHandler,
252
262
  // but there's an ownership problem: CallHandler owns the arena, and so would
253
263
  // get destroyed before the base class Call destructor runs, leading to
254
264
  // UB/crash. Investigate another path.
255
265
  return (new ServerCall(std::move(client_initial_metadata),
256
266
  std::move(call_handler), server, cq,
257
- std::move(parent_arena)))
267
+ publish_initial_metadata, std::move(parent_arena)))
258
268
  ->c_ptr();
259
269
  }
260
270
 
@@ -63,6 +63,7 @@ class ServerCall final : public Call, public DualRefCounted<ServerCall> {
63
63
  ServerCall(ClientMetadataHandle client_initial_metadata,
64
64
  CallHandler call_handler, ServerInterface* server,
65
65
  grpc_completion_queue* cq,
66
+ grpc_metadata_array* publish_initial_metadata,
66
67
  RefCountedPtr<Arena> parent_arena = nullptr)
67
68
  : Call(false,
68
69
  client_initial_metadata->get(GrpcTimeoutMetadata())
@@ -78,6 +79,9 @@ class ServerCall final : public Call, public DualRefCounted<ServerCall> {
78
79
  parent_ctx->arena = std::move(parent_arena);
79
80
  arena()->SetContext<ParentCallContext>(parent_ctx);
80
81
  }
82
+ ProcessIncomingInitialMetadata(*client_initial_metadata_stored_);
83
+ PublishMetadataArray(client_initial_metadata_stored_.get(),
84
+ publish_initial_metadata, false);
81
85
  SourceConstructed();
82
86
  }
83
87
 
@@ -92,9 +96,7 @@ class ServerCall final : public Call, public DualRefCounted<ServerCall> {
92
96
  bool is_trailers_only() const override {
93
97
  Crash("is_trailers_only not implemented for server calls");
94
98
  }
95
- absl::string_view GetServerAuthority() const override {
96
- Crash("unimplemented");
97
- }
99
+ absl::string_view GetServerAuthority() const override;
98
100
  grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
99
101
  bool is_notify_tag_closure) override;
100
102
  void FailBatchImmediately(void* notify_tag, bool is_notify_tag_closure,
@@ -65,11 +65,6 @@ void grpc_client_channel_global_init_backup_polling() {
65
65
  g_backup_polling_disabled = grpc_core::IsEventEngineClientEnabled() &&
66
66
  grpc_core::IsEventEngineListenerEnabled() &&
67
67
  grpc_core::IsEventEngineDnsEnabled();
68
- #ifdef GRPC_PYTHON_BUILD
69
- if (!grpc_core::IsEventEnginePollerForPythonEnabled()) {
70
- g_backup_polling_disabled = false;
71
- }
72
- #endif
73
68
  if (g_backup_polling_disabled) {
74
69
  return;
75
70
  }
@@ -159,21 +154,11 @@ static void g_poller_init_locked() {
159
154
  }
160
155
  }
161
156
 
162
- static bool g_can_poll_in_background() {
163
- #ifndef GRPC_PYTHON_BUILD
164
- return grpc_iomgr_run_in_background();
165
- #else
166
- // No iomgr "event_engines" (not to be confused with the new EventEngine)
167
- // are able to run in background.
168
- return false;
169
- #endif
170
- }
171
-
172
157
  void grpc_client_channel_start_backup_polling(
173
158
  grpc_pollset_set* interested_parties) {
174
159
  if (g_backup_polling_disabled ||
175
160
  g_poll_interval == grpc_core::Duration::Zero() ||
176
- g_can_poll_in_background()) {
161
+ grpc_iomgr_run_in_background()) {
177
162
  return;
178
163
  }
179
164
  gpr_mu_lock(&g_poller_mu);
@@ -193,7 +178,7 @@ void grpc_client_channel_stop_backup_polling(
193
178
  grpc_pollset_set* interested_parties) {
194
179
  if (g_backup_polling_disabled ||
195
180
  g_poll_interval == grpc_core::Duration::Zero() ||
196
- g_can_poll_in_background()) {
181
+ grpc_iomgr_run_in_background()) {
197
182
  return;
198
183
  }
199
184
  grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset);
@@ -404,20 +404,18 @@ void ClientChannel::SubchannelWrapper::Orphaned() {
404
404
  }
405
405
  self->client_channel_->subchannel_map_.erase(it);
406
406
  }
407
- if (IsSubchannelWrapperCleanupOnOrphanEnabled()) {
408
- // We need to make sure that the internal subchannel gets unreffed
409
- // inside of the WorkSerializer, so that updates to the local
410
- // subchannel pool are properly synchronized. To that end, we
411
- // drop our ref to the internal subchannel here. We also cancel
412
- // any watchers that were not properly cancelled, in case any of
413
- // them are holding a ref to the internal subchannel.
414
- for (const auto& [_, watcher] : self->watcher_map_) {
415
- self->subchannel_->CancelConnectivityStateWatch(watcher);
416
- }
417
- self->watcher_map_.clear();
418
- self->data_watchers_.clear();
419
- self->subchannel_.reset();
407
+ // We need to make sure that the internal subchannel gets unreffed
408
+ // inside of the WorkSerializer, so that updates to the local
409
+ // subchannel pool are properly synchronized. To that end, we
410
+ // drop our ref to the internal subchannel here. We also cancel
411
+ // any watchers that were not properly cancelled, in case any of
412
+ // them are holding a ref to the internal subchannel.
413
+ for (const auto& [_, watcher] : self->watcher_map_) {
414
+ self->subchannel_->CancelConnectivityStateWatch(watcher);
420
415
  }
416
+ self->watcher_map_.clear();
417
+ self->data_watchers_.clear();
418
+ self->subchannel_.reset();
421
419
  });
422
420
  }
423
421
 
@@ -898,10 +896,15 @@ void ClientChannel::Ping(grpc_completion_queue*, void*) {
898
896
  grpc_call* ClientChannel::CreateCall(
899
897
  grpc_call* parent_call, uint32_t propagation_mask,
900
898
  grpc_completion_queue* cq, grpc_pollset_set* /*pollset_set_alternative*/,
901
- Slice path, std::optional<Slice> authority, Timestamp deadline, bool) {
899
+ Slice path, std::optional<Slice> authority, Timestamp deadline,
900
+ bool /*registered_method*/,
901
+ std::optional<absl::FunctionRef<void(Arena*)>> arena_init_function) {
902
902
  auto arena = call_arena_allocator()->MakeArena();
903
903
  arena->SetContext<grpc_event_engine::experimental::EventEngine>(
904
904
  event_engine());
905
+ if (arena_init_function.has_value()) {
906
+ (*arena_init_function)(arena.get());
907
+ }
905
908
  return MakeClientCall(parent_call, propagation_mask, cq, std::move(path),
906
909
  std::move(authority), false, deadline,
907
910
  compression_options(), std::move(arena), Ref());
@@ -75,7 +75,9 @@ class ClientChannel : public Channel {
75
75
  grpc_completion_queue* cq,
76
76
  grpc_pollset_set* /*pollset_set_alternative*/,
77
77
  Slice path, std::optional<Slice> authority,
78
- Timestamp deadline, bool registered_method) override;
78
+ Timestamp deadline, bool registered_method,
79
+ std::optional<absl::FunctionRef<void(Arena*)>>
80
+ arena_init_function) override;
79
81
 
80
82
  void StartCall(UnstartedCallHandler unstarted_handler) override;
81
83
 
@@ -465,20 +465,18 @@ class ClientChannelFilter::SubchannelWrapper final
465
465
  }
466
466
  chand_->subchannel_map_.erase(it);
467
467
  }
468
- if (IsSubchannelWrapperCleanupOnOrphanEnabled()) {
469
- // We need to make sure that the internal subchannel gets unreffed
470
- // inside of the WorkSerializer, so that updates to the local
471
- // subchannel pool are properly synchronized. To that end, we
472
- // drop our ref to the internal subchannel here. We also cancel
473
- // any watchers that were not properly cancelled, in case any of
474
- // them are holding a ref to the internal subchannel.
475
- for (const auto& [_, watcher] : watcher_map_) {
476
- subchannel_->CancelConnectivityStateWatch(watcher);
477
- }
478
- watcher_map_.clear();
479
- data_watchers_.clear();
480
- subchannel_.reset();
468
+ // We need to make sure that the internal subchannel gets unreffed
469
+ // inside of the WorkSerializer, so that updates to the local
470
+ // subchannel pool are properly synchronized. To that end, we
471
+ // drop our ref to the internal subchannel here. We also cancel
472
+ // any watchers that were not properly cancelled, in case any of
473
+ // them are holding a ref to the internal subchannel.
474
+ for (const auto& [_, watcher] : watcher_map_) {
475
+ subchannel_->CancelConnectivityStateWatch(watcher);
481
476
  }
477
+ watcher_map_.clear();
478
+ data_watchers_.clear();
479
+ subchannel_.reset();
482
480
  WeakUnref(DEBUG_LOCATION, "subchannel map cleanup");
483
481
  });
484
482
  }
@@ -16,14 +16,12 @@
16
16
 
17
17
  #include "src/core/client_channel/client_channel_service_config.h"
18
18
 
19
- #include <grpc/support/port_platform.h>
20
-
21
19
  #include <map>
22
20
  #include <optional>
23
21
  #include <utility>
24
22
 
23
+ #include "src/core/config/experiment_env_var.h"
25
24
  #include "src/core/load_balancing/lb_policy_registry.h"
26
- #include "src/core/util/env.h"
27
25
  #include "absl/status/status.h"
28
26
  #include "absl/status/statusor.h"
29
27
  #include "absl/strings/ascii.h"
@@ -37,19 +35,13 @@ namespace internal {
37
35
 
38
36
  namespace {
39
37
 
40
- bool ConnectionScalingEnabled() {
41
- auto value =
42
- GetEnv("GRPC_EXPERIMENTAL_MAX_CONCURRENT_STREAMS_CONNECTION_SCALING");
43
- if (!value.has_value()) return false;
44
- bool parsed_value;
45
- bool parse_succeeded = gpr_parse_bool_value(value->c_str(), &parsed_value);
46
- return parse_succeeded && parsed_value;
47
- }
48
-
49
38
  class ConnectionScalingJsonArgs final : public JsonArgs {
50
39
  public:
51
40
  bool IsEnabled(absl::string_view key) const override {
52
- if (key == "connection_scaling") return ConnectionScalingEnabled();
41
+ if (key == "connection_scaling") {
42
+ return IsExperimentEnvVarEnabled(
43
+ "GRPC_EXPERIMENTAL_MAX_CONCURRENT_STREAMS_CONNECTION_SCALING");
44
+ }
53
45
  return true;
54
46
  }
55
47
  };
@@ -71,10 +71,14 @@ grpc_call* DirectChannel::CreateCall(
71
71
  grpc_call* parent_call, uint32_t propagation_mask,
72
72
  grpc_completion_queue* cq, grpc_pollset_set* /*pollset_set_alternative*/,
73
73
  Slice path, std::optional<Slice> authority, Timestamp deadline,
74
- bool /*registered_method*/) {
74
+ bool /*registered_method*/,
75
+ std::optional<absl::FunctionRef<void(Arena*)>> arena_init_function) {
75
76
  auto arena = call_arena_allocator()->MakeArena();
76
77
  arena->SetContext<grpc_event_engine::experimental::EventEngine>(
77
78
  event_engine_.get());
79
+ if (arena_init_function.has_value()) {
80
+ (*arena_init_function)(arena.get());
81
+ }
78
82
  return MakeClientCall(parent_call, propagation_mask, cq, std::move(path),
79
83
  std::move(authority), false, deadline,
80
84
  compression_options(), std::move(arena), Ref());
@@ -62,7 +62,9 @@ class DirectChannel final : public Channel {
62
62
  grpc_completion_queue* cq,
63
63
  grpc_pollset_set* pollset_set_alternative, Slice path,
64
64
  std::optional<Slice> authority, Timestamp deadline,
65
- bool registered_method) override;
65
+ bool registered_method,
66
+ std::optional<absl::FunctionRef<void(Arena*)>>
67
+ arena_init_function) override;
66
68
  grpc_event_engine::experimental::EventEngine* event_engine() const override {
67
69
  return event_engine_.get();
68
70
  }
@@ -0,0 +1,30 @@
1
+ // Copyright 2026 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "src/core/config/experiment_env_var.h"
16
+
17
+ #include "src/core/util/env.h"
18
+ #include "src/core/util/string.h"
19
+
20
+ namespace grpc_core {
21
+
22
+ bool IsExperimentEnvVarEnabled(const char* name, bool default_value) {
23
+ auto value = GetEnv(name);
24
+ if (!value.has_value()) return default_value;
25
+ bool parsed_value;
26
+ bool parse_succeeded = gpr_parse_bool_value(value->c_str(), &parsed_value);
27
+ return parse_succeeded && parsed_value;
28
+ }
29
+
30
+ } // namespace grpc_core
@@ -0,0 +1,26 @@
1
+ // Copyright 2026 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef GRPC_SRC_CORE_CONFIG_EXPERIMENT_ENV_VAR_H
16
+ #define GRPC_SRC_CORE_CONFIG_EXPERIMENT_ENV_VAR_H
17
+
18
+ namespace grpc_core {
19
+
20
+ // Returns true if the specified experiment env var is enabled.
21
+ // If the env var is not set, returns default_value.
22
+ bool IsExperimentEnvVarEnabled(const char* name, bool default_value = false);
23
+
24
+ } // namespace grpc_core
25
+
26
+ #endif // GRPC_SRC_CORE_CONFIG_EXPERIMENT_ENV_VAR_H
@@ -56,8 +56,8 @@ RegionalAccessBoundaryFetcher::Create(
56
56
  std::optional<BackOff::Options> backoff_options) {
57
57
  auto uri = URI::Parse(lookup_url);
58
58
  if (!uri.ok()) {
59
- LOG(WARNING) << "Invalid RegionalAccessBoundary lookup URI \"" << lookup_url
60
- << "\" (" << uri.status() << "); RAB data will not be fetched";
59
+ LOG(INFO) << "Invalid RegionalAccessBoundary lookup URI \"" << lookup_url
60
+ << "\" (" << uri.status() << "); RAB data will not be fetched";
61
61
  return nullptr;
62
62
  }
63
63
  return MakeRefCounted<RegionalAccessBoundaryFetcher>(
@@ -103,7 +103,7 @@ void RegionalAccessBoundaryFetcher::OnFetchFailure(
103
103
  if (response_body.data() != nullptr) {
104
104
  absl::StrAppend(&log_message, ", Body: ", response_body);
105
105
  }
106
- LOG(WARNING) << log_message;
106
+ LOG(INFO) << log_message;
107
107
  next_fetch_time_ = Timestamp::Now() + backoff_.NextAttemptDelay();
108
108
  pending_request_.reset();
109
109
  }
@@ -380,9 +380,9 @@ void EmailFetcher::OnEmailFetchComplete(absl::string_view email) {
380
380
  void EmailFetcher::OnEmailFetchError(grpc_error_handle error) {
381
381
  MutexLock lock(&mu_);
382
382
  if (std::holds_alternative<OrphanablePtr<EmailRequest>>(state_)) {
383
- LOG_EVERY_N_SEC(ERROR, 60) << "Regional Access Boundary fetch skipped due "
384
- "to service account email fetch failure: "
385
- << StatusToString(error);
383
+ LOG_EVERY_N_SEC(INFO, 60) << "Regional Access Boundary fetch skipped due "
384
+ "to service account email fetch failure: "
385
+ << StatusToString(error);
386
386
  state_ = OrphanablePtr<EmailRequest>(
387
387
  nullptr); // Reset to allow retry on next invocation.
388
388
  next_fetch_earliest_time_ = Timestamp::Now() + backoff_.NextAttemptDelay();
@@ -39,6 +39,7 @@
39
39
  #include "src/core/lib/iomgr/iomgr_fwd.h"
40
40
  #include "src/core/lib/promise/arena_promise.h"
41
41
  #include "src/core/lib/promise/promise.h"
42
+ #include "src/core/telemetry/metrics.h"
42
43
  #include "src/core/transport/auth_context.h"
43
44
  #include "src/core/tsi/ssl_transport_security.h"
44
45
  #include "src/core/tsi/transport_security.h"
@@ -103,13 +104,19 @@ class grpc_ssl_channel_security_connector final
103
104
  grpc_core::HandshakeManager* handshake_mgr) override {
104
105
  // Instantiate TSI handshaker.
105
106
  tsi_handshaker* tsi_hs = nullptr;
107
+ auto stats_plugin_group = args.GetObject<
108
+ grpc_core::GlobalStatsPluginRegistry::StatsPluginGroup>();
109
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope =
110
+ stats_plugin_group != nullptr ? stats_plugin_group->GetCollectionScope()
111
+ : nullptr;
106
112
  tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
107
113
  client_handshaker_factory_,
108
114
  overridden_target_name_.empty() ? target_name_.c_str()
109
115
  : overridden_target_name_.c_str(),
110
116
  /*network_bio_buf_size=*/0,
111
117
  /*ssl_bio_buf_size=*/0,
112
- args.GetOwnedString(GRPC_ARG_TRANSPORT_PROTOCOLS), &tsi_hs);
118
+ args.GetOwnedString(GRPC_ARG_TRANSPORT_PROTOCOLS),
119
+ std::move(collection_scope), &tsi_hs);
113
120
  if (result != TSI_OK) {
114
121
  LOG(ERROR) << "Handshaker creation failed with error "
115
122
  << tsi_result_to_string(result);
@@ -274,9 +281,14 @@ class grpc_ssl_server_security_connector
274
281
  // Instantiate TSI handshaker.
275
282
  try_fetch_ssl_server_credentials();
276
283
  tsi_handshaker* tsi_hs = nullptr;
284
+ auto stats_plugin_group = args.GetObject<
285
+ grpc_core::GlobalStatsPluginRegistry::StatsPluginGroup>();
286
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope =
287
+ stats_plugin_group != nullptr ? stats_plugin_group->GetCollectionScope()
288
+ : nullptr;
277
289
  tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
278
290
  server_handshaker_factory_, /*network_bio_buf_size=*/0,
279
- /*ssl_bio_buf_size=*/0, &tsi_hs);
291
+ /*ssl_bio_buf_size=*/0, std::move(collection_scope), &tsi_hs);
280
292
  if (result != TSI_OK) {
281
293
  LOG(ERROR) << "Handshaker creation failed with error "
282
294
  << tsi_result_to_string(result);