pull/35949/head
Craig Tiller 9 months ago
parent 5227db884d
commit 7fb4afbd69
  1. 24
      bazel/experiments.bzl
  2. 15
      src/core/ext/transport/chttp2/transport/parsing.cc
  3. 8
      src/core/ext/transport/chttp2/transport/writing.cc
  4. 63
      src/core/lib/experiments/experiments.cc
  5. 30
      src/core/lib/experiments/experiments.h
  6. 23
      src/core/lib/experiments/experiments.yaml
  7. 6
      src/core/lib/experiments/rollouts.yaml

@ -40,7 +40,6 @@ EXPERIMENT_ENABLES = {
"chaotic_good": "chaotic_good,event_engine_client,event_engine_listener,promise_based_client_call,promise_based_server_call",
"registered_method_lookup_in_transport": "registered_method_lookup_in_transport",
"promise_based_inproc_transport": "event_engine_client,event_engine_listener,promise_based_client_call,promise_based_inproc_transport,promise_based_server_call,registered_method_lookup_in_transport",
"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",
@ -55,8 +54,6 @@ EXPERIMENT_ENABLES = {
"v3_server_auth_filter": "v3_server_auth_filter",
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
"work_serializer_dispatch": "event_engine_client,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",
}
@ -71,9 +68,6 @@ EXPERIMENTS = {
"dbg": {
},
"off": {
"bad_client_test": [
"rfc_max_concurrent_streams",
],
"compression_test": [
"v3_compression_filter",
],
@ -130,10 +124,6 @@ EXPERIMENTS = {
"event_engine_listener_test": [
"event_engine_listener",
],
"flow_control_test": [
"write_size_cap",
"write_size_policy",
],
"lb_unit_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
@ -153,9 +143,6 @@ EXPERIMENTS = {
"dbg": {
},
"off": {
"bad_client_test": [
"rfc_max_concurrent_streams",
],
"compression_test": [
"v3_compression_filter",
],
@ -206,10 +193,6 @@ EXPERIMENTS = {
"credential_token_tests": [
"absl_base64",
],
"flow_control_test": [
"write_size_cap",
"write_size_policy",
],
"lb_unit_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
@ -229,9 +212,6 @@ EXPERIMENTS = {
"dbg": {
},
"off": {
"bad_client_test": [
"rfc_max_concurrent_streams",
],
"cancel_ares_query_test": [
"event_engine_dns",
],
@ -299,10 +279,6 @@ EXPERIMENTS = {
"event_engine_listener_test": [
"event_engine_listener",
],
"flow_control_test": [
"write_size_cap",
"write_size_policy",
],
"lb_unit_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",

@ -644,17 +644,12 @@ static grpc_error_handle init_header_frame_parser(grpc_chttp2_transport* t,
return init_header_skip_frame_parser(t, priority_type, is_eoh);
} else if (GPR_UNLIKELY(t->stream_map.size() + t->extra_streams >=
t->settings.acked().max_concurrent_streams())) {
if (grpc_core::IsRfcMaxConcurrentStreamsEnabled()) {
++t->num_pending_induced_frames;
grpc_slice_buffer_add(
&t->qbuf,
grpc_chttp2_rst_stream_create(t->incoming_stream_id,
++t->num_pending_induced_frames;
grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_rst_stream_create(
t->incoming_stream_id,
GRPC_HTTP2_REFUSED_STREAM, nullptr));
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM);
return init_header_skip_frame_parser(t, priority_type, is_eoh);
} else {
return GRPC_ERROR_CREATE("Max stream count exceeded");
}
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM);
return init_header_skip_frame_parser(t, priority_type, is_eoh);
} else if (GPR_UNLIKELY(
t->max_concurrent_streams_overload_protection &&
t->streams_allocated.load(std::memory_order_relaxed) >

@ -368,9 +368,7 @@ class WriteContext {
private:
grpc_chttp2_transport* const t_;
size_t target_write_size_ = grpc_core::IsWriteSizePolicyEnabled()
? t_->write_size_policy.WriteTargetSize()
: 1024 * 1024;
size_t target_write_size_ = t_->write_size_policy.WriteTargetSize();
// stats histogram counters: we increment these throughout this function,
// and at the end publish to the central stats histograms
@ -402,9 +400,7 @@ class DataSendContext {
std::min<int64_t>(
{t_->settings.peer().max_frame_size(), stream_remote_window(),
t_->flow_control.remote_window(),
grpc_core::IsWriteSizeCapEnabled()
? static_cast<int64_t>(write_context_->target_write_size())
: std::numeric_limits<uint32_t>::max()}),
static_cast<int64_t>(write_context_->target_write_size())}),
0, std::numeric_limits<uint32_t>::max());
}

@ -116,11 +116,6 @@ const uint8_t required_experiments_promise_based_inproc_transport[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdPromiseBasedServerCall),
static_cast<uint8_t>(
grpc_core::kExperimentIdRegisteredMethodLookupInTransport)};
const char* const description_rfc_max_concurrent_streams =
"If set, enable rfc-compliant behavior (cancellation) in the advent that "
"max concurrent streams are exceeded in chttp2. See "
"https://www.rfc-editor.org/rfc/rfc9113.html#section-5.1.2.";
const char* const additional_constraints_rfc_max_concurrent_streams = "{}";
const char* const description_round_robin_delegate_to_pick_first =
"Change round_robin code to delegate to pick_first as per dualstack "
"backend design.";
@ -175,14 +170,6 @@ const char* const description_work_serializer_dispatch =
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
const char* const description_write_size_policy =
"Try to size writes such that they don't create too large of a backlog";
const char* const additional_constraints_write_size_policy = "{}";
const char* const description_write_size_cap =
"Limit outgoing writes proportional to the target write size";
const char* const additional_constraints_write_size_cap = "{}";
const uint8_t required_experiments_write_size_cap[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdWriteSizePolicy)};
const char* const description_wrr_delegate_to_pick_first =
"Change WRR code to delegate to pick_first as per dualstack backend "
"design.";
@ -251,9 +238,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
description_promise_based_inproc_transport,
additional_constraints_promise_based_inproc_transport,
required_experiments_promise_based_inproc_transport, 3, false, false},
{"rfc_max_concurrent_streams", description_rfc_max_concurrent_streams,
additional_constraints_rfc_max_concurrent_streams, nullptr, 0, false,
true},
{"round_robin_delegate_to_pick_first",
description_round_robin_delegate_to_pick_first,
additional_constraints_round_robin_delegate_to_pick_first, nullptr, 0,
@ -291,11 +275,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
{"write_size_policy", description_write_size_policy,
additional_constraints_write_size_policy, nullptr, 0, true, true},
{"write_size_cap", description_write_size_cap,
additional_constraints_write_size_cap, required_experiments_write_size_cap,
1, true, true},
{"wrr_delegate_to_pick_first", description_wrr_delegate_to_pick_first,
additional_constraints_wrr_delegate_to_pick_first, nullptr, 0, true, true},
};
@ -396,11 +375,6 @@ const uint8_t required_experiments_promise_based_inproc_transport[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdPromiseBasedServerCall),
static_cast<uint8_t>(
grpc_core::kExperimentIdRegisteredMethodLookupInTransport)};
const char* const description_rfc_max_concurrent_streams =
"If set, enable rfc-compliant behavior (cancellation) in the advent that "
"max concurrent streams are exceeded in chttp2. See "
"https://www.rfc-editor.org/rfc/rfc9113.html#section-5.1.2.";
const char* const additional_constraints_rfc_max_concurrent_streams = "{}";
const char* const description_round_robin_delegate_to_pick_first =
"Change round_robin code to delegate to pick_first as per dualstack "
"backend design.";
@ -455,14 +429,6 @@ const char* const description_work_serializer_dispatch =
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
const char* const description_write_size_policy =
"Try to size writes such that they don't create too large of a backlog";
const char* const additional_constraints_write_size_policy = "{}";
const char* const description_write_size_cap =
"Limit outgoing writes proportional to the target write size";
const char* const additional_constraints_write_size_cap = "{}";
const uint8_t required_experiments_write_size_cap[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdWriteSizePolicy)};
const char* const description_wrr_delegate_to_pick_first =
"Change WRR code to delegate to pick_first as per dualstack backend "
"design.";
@ -531,9 +497,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
description_promise_based_inproc_transport,
additional_constraints_promise_based_inproc_transport,
required_experiments_promise_based_inproc_transport, 3, false, false},
{"rfc_max_concurrent_streams", description_rfc_max_concurrent_streams,
additional_constraints_rfc_max_concurrent_streams, nullptr, 0, false,
true},
{"round_robin_delegate_to_pick_first",
description_round_robin_delegate_to_pick_first,
additional_constraints_round_robin_delegate_to_pick_first, nullptr, 0,
@ -571,11 +534,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
{"write_size_policy", description_write_size_policy,
additional_constraints_write_size_policy, nullptr, 0, true, true},
{"write_size_cap", description_write_size_cap,
additional_constraints_write_size_cap, required_experiments_write_size_cap,
1, true, true},
{"wrr_delegate_to_pick_first", description_wrr_delegate_to_pick_first,
additional_constraints_wrr_delegate_to_pick_first, nullptr, 0, true, true},
};
@ -676,11 +634,6 @@ const uint8_t required_experiments_promise_based_inproc_transport[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdPromiseBasedServerCall),
static_cast<uint8_t>(
grpc_core::kExperimentIdRegisteredMethodLookupInTransport)};
const char* const description_rfc_max_concurrent_streams =
"If set, enable rfc-compliant behavior (cancellation) in the advent that "
"max concurrent streams are exceeded in chttp2. See "
"https://www.rfc-editor.org/rfc/rfc9113.html#section-5.1.2.";
const char* const additional_constraints_rfc_max_concurrent_streams = "{}";
const char* const description_round_robin_delegate_to_pick_first =
"Change round_robin code to delegate to pick_first as per dualstack "
"backend design.";
@ -735,14 +688,6 @@ const char* const description_work_serializer_dispatch =
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
const char* const description_write_size_policy =
"Try to size writes such that they don't create too large of a backlog";
const char* const additional_constraints_write_size_policy = "{}";
const char* const description_write_size_cap =
"Limit outgoing writes proportional to the target write size";
const char* const additional_constraints_write_size_cap = "{}";
const uint8_t required_experiments_write_size_cap[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdWriteSizePolicy)};
const char* const description_wrr_delegate_to_pick_first =
"Change WRR code to delegate to pick_first as per dualstack backend "
"design.";
@ -811,9 +756,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
description_promise_based_inproc_transport,
additional_constraints_promise_based_inproc_transport,
required_experiments_promise_based_inproc_transport, 3, false, false},
{"rfc_max_concurrent_streams", description_rfc_max_concurrent_streams,
additional_constraints_rfc_max_concurrent_streams, nullptr, 0, false,
true},
{"round_robin_delegate_to_pick_first",
description_round_robin_delegate_to_pick_first,
additional_constraints_round_robin_delegate_to_pick_first, nullptr, 0,
@ -851,11 +793,6 @@ const ExperimentMetadata g_experiment_metadata[] = {
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
{"write_size_policy", description_write_size_policy,
additional_constraints_write_size_policy, nullptr, 0, true, true},
{"write_size_cap", description_write_size_cap,
additional_constraints_write_size_cap, required_experiments_write_size_cap,
1, true, true},
{"wrr_delegate_to_pick_first", description_wrr_delegate_to_pick_first,
additional_constraints_wrr_delegate_to_pick_first, nullptr, 0, true, true},
};

@ -96,7 +96,6 @@ inline bool IsChaoticGoodEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() { return true; }
inline bool IsPromiseBasedInprocTransportEnabled() { return false; }
inline bool IsRfcMaxConcurrentStreamsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST
inline bool IsRoundRobinDelegateToPickFirstEnabled() { return true; }
inline bool IsRstpitEnabled() { return false; }
@ -113,10 +112,6 @@ inline bool IsV3ServerAuthFilterEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; }
inline bool IsWorkSerializerDispatchEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_POLICY
inline bool IsWriteSizePolicyEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_CAP
inline bool IsWriteSizeCapEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST
inline bool IsWrrDelegateToPickFirstEnabled() { return true; }
@ -161,7 +156,6 @@ inline bool IsChaoticGoodEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() { return true; }
inline bool IsPromiseBasedInprocTransportEnabled() { return false; }
inline bool IsRfcMaxConcurrentStreamsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST
inline bool IsRoundRobinDelegateToPickFirstEnabled() { return true; }
inline bool IsRstpitEnabled() { return false; }
@ -178,10 +172,6 @@ inline bool IsV3ServerAuthFilterEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; }
inline bool IsWorkSerializerDispatchEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_POLICY
inline bool IsWriteSizePolicyEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_CAP
inline bool IsWriteSizeCapEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST
inline bool IsWrrDelegateToPickFirstEnabled() { return true; }
@ -226,7 +216,6 @@ inline bool IsChaoticGoodEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_REGISTERED_METHOD_LOOKUP_IN_TRANSPORT
inline bool IsRegisteredMethodLookupInTransportEnabled() { return true; }
inline bool IsPromiseBasedInprocTransportEnabled() { return false; }
inline bool IsRfcMaxConcurrentStreamsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST
inline bool IsRoundRobinDelegateToPickFirstEnabled() { return true; }
inline bool IsRstpitEnabled() { return false; }
@ -243,10 +232,6 @@ inline bool IsV3ServerAuthFilterEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; }
inline bool IsWorkSerializerDispatchEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_POLICY
inline bool IsWriteSizePolicyEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_CAP
inline bool IsWriteSizeCapEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST
inline bool IsWrrDelegateToPickFirstEnabled() { return true; }
#endif
@ -276,7 +261,6 @@ enum ExperimentIds {
kExperimentIdChaoticGood,
kExperimentIdRegisteredMethodLookupInTransport,
kExperimentIdPromiseBasedInprocTransport,
kExperimentIdRfcMaxConcurrentStreams,
kExperimentIdRoundRobinDelegateToPickFirst,
kExperimentIdRstpit,
kExperimentIdScheduleCancellationOverWrite,
@ -291,8 +275,6 @@ enum ExperimentIds {
kExperimentIdV3ServerAuthFilter,
kExperimentIdWorkSerializerClearsTimeCache,
kExperimentIdWorkSerializerDispatch,
kExperimentIdWriteSizePolicy,
kExperimentIdWriteSizeCap,
kExperimentIdWrrDelegateToPickFirst,
kNumExperiments
};
@ -388,10 +370,6 @@ inline bool IsRegisteredMethodLookupInTransportEnabled() {
inline bool IsPromiseBasedInprocTransportEnabled() {
return IsExperimentEnabled(kExperimentIdPromiseBasedInprocTransport);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_RFC_MAX_CONCURRENT_STREAMS
inline bool IsRfcMaxConcurrentStreamsEnabled() {
return IsExperimentEnabled(kExperimentIdRfcMaxConcurrentStreams);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST
inline bool IsRoundRobinDelegateToPickFirstEnabled() {
return IsExperimentEnabled(kExperimentIdRoundRobinDelegateToPickFirst);
@ -448,14 +426,6 @@ inline bool IsWorkSerializerClearsTimeCacheEnabled() {
inline bool IsWorkSerializerDispatchEnabled() {
return IsExperimentEnabled(kExperimentIdWorkSerializerDispatch);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_POLICY
inline bool IsWriteSizePolicyEnabled() {
return IsExperimentEnabled(kExperimentIdWriteSizePolicy);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_WRITE_SIZE_CAP
inline bool IsWriteSizeCapEnabled() {
return IsExperimentEnabled(kExperimentIdWriteSizeCap);
}
#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST
inline bool IsWrrDelegateToPickFirstEnabled() {
return IsExperimentEnabled(kExperimentIdWrrDelegateToPickFirst);

@ -195,14 +195,6 @@
expiry: 2024/03/31
owner: yashkt@google.com
test_tags: ["surface_registered_method_lookup"]
- name: rfc_max_concurrent_streams
description:
If set, enable rfc-compliant behavior (cancellation) in the advent that
max concurrent streams are exceeded in chttp2.
See https://www.rfc-editor.org/rfc/rfc9113.html#section-5.1.2.
expiry: 2024/03/03
owner: ctiller@google.com
test_tags: [bad_client_test]
- name: round_robin_delegate_to_pick_first
description:
Change round_robin code to delegate to pick_first as per dualstack
@ -213,7 +205,7 @@
- name: rstpit
description:
On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short duration
expiry: 2024/03/03
expiry: 2024/08/03
owner: ctiller@google.com
test_tags: [flow_control_test]
- name: schedule_cancellation_over_write
@ -291,19 +283,6 @@
owner: ysseung@google.com
test_tags: ["core_end2end_test", "cpp_end2end_test", "xds_end2end_test", "lb_unit_test"]
requires: ["event_engine_client"]
- name: write_size_cap
description:
Limit outgoing writes proportional to the target write size
expiry: 2024/03/03
owner: ctiller@google.com
test_tags: [flow_control_test]
requires: [write_size_policy]
- name: write_size_policy
description:
Try to size writes such that they don't create too large of a backlog
expiry: 2024/03/03
owner: ctiller@google.com
test_tags: [flow_control_test]
- name: wrr_delegate_to_pick_first
description:
Change WRR code to delegate to pick_first as per dualstack

@ -101,8 +101,6 @@
default: false
- name: registered_method_lookup_in_transport
default: true
- name: rfc_max_concurrent_streams
default: false
- name: round_robin_delegate_to_pick_first
default: true
- name: rstpit
@ -123,9 +121,5 @@
default: true
- name: work_serializer_dispatch
default: false
- name: write_size_cap
default: true
- name: write_size_policy
default: true
- name: wrr_delegate_to_pick_first
default: true

Loading…
Cancel
Save