HTTP2: Don't throttle pings from the server (#29053)

* HTTP2: Don't throttle pings from the server

* Reviewer comments
pull/29070/head
Yash Tibrewal 3 years ago committed by GitHub
parent c9946c2183
commit a1620ce2bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      include/grpc/impl/codegen/grpc_types.h
  2. 36
      src/core/ext/transport/chttp2/transport/writing.cc

@ -219,7 +219,7 @@ typedef struct {
"grpc.http2.min_ping_interval_without_data_ms"
/** Channel arg to override the http2 :scheme header */
#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
/** How many pings can we send before needing to send a
/** How many pings can the client send before needing to send a
data/header frame? (0 indicates that an infinite number of
pings can be sent without sending a data frame or header frame) */
#define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \
@ -241,8 +241,8 @@ typedef struct {
not receive the ping ack, it will close the transport. Int valued,
milliseconds. */
#define GRPC_ARG_KEEPALIVE_TIMEOUT_MS "grpc.keepalive_timeout_ms"
/** Is it permissible to send keepalive pings without any outstanding streams.
Int valued, 0(false)/1(true). */
/** Is it permissible to send keepalive pings from the client without any
outstanding streams. Int valued, 0(false)/1(true). */
#define GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS \
"grpc.keepalive_permit_without_calls"
/** Default authority to pass if none specified on call construction. A string.

@ -60,15 +60,15 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
}
return;
}
if (t->ping_state.pings_before_data_required == 0 &&
if (t->is_client && t->ping_state.pings_before_data_required == 0 &&
t->ping_policy.max_pings_without_data != 0) {
/* need to receive something of substance before sending a ping again */
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) ||
GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace) ||
GRPC_TRACE_FLAG_ENABLED(grpc_keepalive_trace)) {
gpr_log(GPR_INFO, "%s: Ping delayed [%s]: too many recent pings: %d/%d",
t->is_client ? "CLIENT" : "SERVER", t->peer_string.c_str(),
t->ping_state.pings_before_data_required,
gpr_log(GPR_INFO,
"CLIENT: Ping delayed [%s]: too many recent pings: %d/%d",
t->peer_string.c_str(), t->ping_state.pings_before_data_required,
t->ping_policy.max_pings_without_data);
}
return;
@ -79,13 +79,22 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
grpc_core::ExecCtx::Get()->InvalidateNow();
grpc_core::Timestamp now = grpc_core::ExecCtx::Get()->Now();
grpc_core::Duration next_allowed_ping_interval =
(t->keepalive_permit_without_calls == 0 &&
grpc_chttp2_stream_map_size(&t->stream_map) == 0)
? grpc_core::Duration::Hours(2)
: grpc_core::Duration::Seconds(
1); /* A second is added to deal with network delays and timing
imprecision */
grpc_core::Duration next_allowed_ping_interval = grpc_core::Duration::Zero();
if (t->is_client) {
next_allowed_ping_interval =
(t->keepalive_permit_without_calls == 0 &&
grpc_chttp2_stream_map_size(&t->stream_map) == 0)
? grpc_core::Duration::Hours(2)
: grpc_core::Duration::Seconds(1); /* A second is added to deal with
network delays and timing imprecision */
} else {
// The gRPC keepalive spec doesn't call for any throttling on the server
// side, but we are adding some throttling for protection anyway.
next_allowed_ping_interval =
t->keepalive_time == grpc_core::Duration::Infinity()
? grpc_core::Duration::Seconds(20)
: t->keepalive_time / 2;
}
grpc_core::Timestamp next_allowed_ping =
t->ping_state.last_ping_sent_time + next_allowed_ping_interval;
@ -96,7 +105,8 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
GRPC_TRACE_FLAG_ENABLED(grpc_keepalive_trace)) {
gpr_log(
GPR_INFO,
"%s: Ping delayed [%s]: not enough time elapsed since last ping. "
"%s: Ping delayed [%s]: not enough time elapsed since last "
"ping. "
" Last ping %" PRId64 ": Next ping %" PRId64 ": Now %" PRId64,
t->is_client ? "CLIENT" : "SERVER", t->peer_string.c_str(),
t->ping_state.last_ping_sent_time.milliseconds_after_process_epoch(),
@ -114,6 +124,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
}
return;
}
t->ping_state.last_ping_sent_time = now;
pq->inflight_id = t->ping_ctr;
t->ping_ctr++;
@ -124,7 +135,6 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_ping_create(false, pq->inflight_id));
GRPC_STATS_INC_HTTP2_PINGS_SENT();
t->ping_state.last_ping_sent_time = now;
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) ||
GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace) ||
GRPC_TRACE_FLAG_ENABLED(grpc_keepalive_trace)) {

Loading…
Cancel
Save