Merge branch 'flowctlN+pure' of github.com:ctiller/grpc into flowctlN

pull/11072/head
Craig Tiller 7 years ago
commit 543ad5c592
  1. 13
      include/grpc/impl/codegen/grpc_types.h
  2. 96
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  3. 2
      src/core/ext/transport/chttp2/transport/frame_ping.c
  4. 4
      src/core/ext/transport/chttp2/transport/internal.h
  5. 7
      src/core/ext/transport/chttp2/transport/parsing.c
  6. 38
      src/core/ext/transport/chttp2/transport/writing.c
  7. 2
      test/core/client_channel/lb_policies_test.c
  8. 11
      test/core/end2end/tests/bad_ping.c
  9. 14
      test/core/end2end/tests/ping.c
  10. 14
      test/core/transport/bdp_estimator_test.c

@ -188,9 +188,14 @@ typedef struct {
#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size" #define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
/** Should BDP probing be performed? */ /** Should BDP probing be performed? */
#define GRPC_ARG_HTTP2_BDP_PROBE "grpc.http2.bdp_probe" #define GRPC_ARG_HTTP2_BDP_PROBE "grpc.http2.bdp_probe"
/** Minimum time (in milliseconds) between successive ping frames being sent */ /** Minimum time between sending successive ping frames without receiving any
#define GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS \ data frame, Int valued, milliseconds. */
#define GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS \
"grpc.http2.min_time_between_pings_ms" "grpc.http2.min_time_between_pings_ms"
/** Minimum allowed time between receiving successive ping frames without
sending any data frame. Int valued, milliseconds */
#define GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS \
"grpc.http2.min_ping_interval_without_data_ms"
/** Channel arg to override the http2 :scheme header */ /** Channel arg to override the http2 :scheme header */
#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
/** How many pings can we send before needing to send a data frame or header /** How many pings can we send before needing to send a data frame or header
@ -202,10 +207,6 @@ typedef struct {
closing the transport? (0 indicates that the server can bear an infinite closing the transport? (0 indicates that the server can bear an infinite
number of misbehaving pings) */ number of misbehaving pings) */
#define GRPC_ARG_HTTP2_MAX_PING_STRIKES "grpc.http2.max_ping_strikes" #define GRPC_ARG_HTTP2_MAX_PING_STRIKES "grpc.http2.max_ping_strikes"
/** Minimum allowed time between two pings without sending any data frame. Int
valued, seconds */
#define GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS \
"grpc.http2.min_ping_interval_without_data_ms"
/** How much data are we willing to queue up per stream if /** How much data are we willing to queue up per stream if
GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */ GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */
#define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size" #define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size"

@ -64,6 +64,11 @@
#define DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS false #define DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS false
#define KEEPALIVE_TIME_BACKOFF_MULTIPLIER 2 #define KEEPALIVE_TIME_BACKOFF_MULTIPLIER 2
#define DEFAULT_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS 300000 /* 5 minutes */
#define DEFAULT_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS 300000 /* 5 minutes */
#define DEFAULT_MAX_PINGS_BETWEEN_DATA 0 /* unlimited */
#define DEFAULT_MAX_PING_STRIKES 2
static int g_default_client_keepalive_time_ms = static int g_default_client_keepalive_time_ms =
DEFAULT_CLIENT_KEEPALIVE_TIME_MS; DEFAULT_CLIENT_KEEPALIVE_TIME_MS;
static int g_default_client_keepalive_timeout_ms = static int g_default_client_keepalive_timeout_ms =
@ -75,6 +80,13 @@ static int g_default_server_keepalive_timeout_ms =
static bool g_default_keepalive_permit_without_calls = static bool g_default_keepalive_permit_without_calls =
DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS; DEFAULT_KEEPALIVE_PERMIT_WITHOUT_CALLS;
static int g_default_min_sent_ping_interval_without_data_ms =
DEFAULT_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS;
static int g_default_min_recv_ping_interval_without_data_ms =
DEFAULT_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS;
static int g_default_max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA;
static int g_default_max_ping_strikes = DEFAULT_MAX_PING_STRIKES;
#define MAX_CLIENT_STREAM_ID 0x7fffffffu #define MAX_CLIENT_STREAM_ID 0x7fffffffu
grpc_tracer_flag grpc_http_trace = GRPC_TRACER_INITIALIZER(false, "http"); grpc_tracer_flag grpc_http_trace = GRPC_TRACER_INITIALIZER(false, "http");
grpc_tracer_flag grpc_flowctl_trace = GRPC_TRACER_INITIALIZER(false, "flowctl"); grpc_tracer_flag grpc_flowctl_trace = GRPC_TRACER_INITIALIZER(false, "flowctl");
@ -150,11 +162,6 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp, static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error); grpc_error *error);
#define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0
#define DEFAULT_MAX_PINGS_BETWEEN_DATA 3
#define DEFAULT_MAX_PING_STRIKES 2
#define DEFAULT_MIN_PING_INTERVAL_WITHOUT_DATA_MS 300000 /* 5 minutes */
/** keepalive-relevant functions */ /** keepalive-relevant functions */
static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error); grpc_error *error);
@ -361,12 +368,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1); GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1);
t->ping_policy = (grpc_chttp2_repeated_ping_policy){ t->ping_policy = (grpc_chttp2_repeated_ping_policy){
.max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA, .max_pings_without_data = g_default_max_pings_without_data,
.min_time_between_pings = .min_sent_ping_interval_without_data = gpr_time_from_millis(
gpr_time_from_millis(DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, GPR_TIMESPAN), g_default_min_sent_ping_interval_without_data_ms, GPR_TIMESPAN),
.max_ping_strikes = DEFAULT_MAX_PING_STRIKES, .max_ping_strikes = g_default_max_ping_strikes,
.min_ping_interval_without_data = gpr_time_from_millis( .min_recv_ping_interval_without_data = gpr_time_from_millis(
DEFAULT_MIN_PING_INTERVAL_WITHOUT_DATA_MS, GPR_TIMESPAN), g_default_min_recv_ping_interval_without_data_ms, GPR_TIMESPAN),
}; };
/* Keepalive setting */ /* Keepalive setting */
@ -426,28 +433,36 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) { GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) {
t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer( t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer(
&channel_args->args[i], &channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_PINGS_BETWEEN_DATA, 0, INT_MAX}); (grpc_integer_options){g_default_max_pings_without_data, 0,
INT_MAX});
} else if (0 == strcmp(channel_args->args[i].key, } else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_MAX_PING_STRIKES)) { GRPC_ARG_HTTP2_MAX_PING_STRIKES)) {
t->ping_policy.max_ping_strikes = grpc_channel_arg_get_integer( t->ping_policy.max_ping_strikes = grpc_channel_arg_get_integer(
&channel_args->args[i], &channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_PING_STRIKES, 0, INT_MAX}); (grpc_integer_options){g_default_max_ping_strikes, 0, INT_MAX});
} else if (0 == strcmp(channel_args->args[i].key, } else if (0 ==
GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS)) { strcmp(
t->ping_policy.min_time_between_pings = gpr_time_from_millis( channel_args->args[i].key,
GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS)) {
t->ping_policy.min_sent_ping_interval_without_data =
gpr_time_from_millis(
grpc_channel_arg_get_integer( grpc_channel_arg_get_integer(
&channel_args->args[i], &channel_args->args[i],
(grpc_integer_options){DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, 0, (grpc_integer_options){
g_default_min_sent_ping_interval_without_data_ms, 0,
INT_MAX}), INT_MAX}),
GPR_TIMESPAN); GPR_TIMESPAN);
} else if (0 == } else if (0 ==
strcmp(channel_args->args[i].key, strcmp(
GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS)) { channel_args->args[i].key,
t->ping_policy.min_ping_interval_without_data = gpr_time_from_millis( GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS)) {
t->ping_policy.min_recv_ping_interval_without_data =
gpr_time_from_millis(
grpc_channel_arg_get_integer( grpc_channel_arg_get_integer(
&channel_args->args[i], &channel_args->args[i],
(grpc_integer_options){ (grpc_integer_options){
DEFAULT_MIN_PING_INTERVAL_WITHOUT_DATA_MS, 0, INT_MAX}), g_default_min_recv_ping_interval_without_data_ms, 0,
INT_MAX}),
GPR_TIMESPAN); GPR_TIMESPAN);
} else if (0 == strcmp(channel_args->args[i].key, } else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) { GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
@ -555,8 +570,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
} }
} }
t->ping_state.pings_before_data_required = /* No pings allowed before receiving a header or data frame. */
t->ping_policy.max_pings_without_data; t->ping_state.pings_before_data_required = 0;
t->ping_state.is_delayed_ping_timer_set = false; t->ping_state.is_delayed_ping_timer_set = false;
t->ping_recv_state.last_ping_recv_time = gpr_inf_past(GPR_CLOCK_MONOTONIC); t->ping_recv_state.last_ping_recv_time = gpr_inf_past(GPR_CLOCK_MONOTONIC);
@ -623,6 +638,9 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "close_transport"); GRPC_ERROR_REF(error), "close_transport");
grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error)); grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error));
if (t->ping_state.is_delayed_ping_timer_set) {
grpc_timer_cancel(exec_ctx, &t->ping_state.delayed_ping_timer);
}
switch (t->keepalive_state) { switch (t->keepalive_state) {
case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING: case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING:
grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer); grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer);
@ -1718,9 +1736,11 @@ static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error) { grpc_error *error) {
grpc_chttp2_transport *t = (grpc_chttp2_transport *)tp; grpc_chttp2_transport *t = (grpc_chttp2_transport *)tp;
t->ping_state.is_delayed_ping_timer_set = false; t->ping_state.is_delayed_ping_timer_set = false;
if (error == GRPC_ERROR_NONE) {
grpc_chttp2_initiate_write(exec_ctx, t, grpc_chttp2_initiate_write(exec_ctx, t,
GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING); GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING);
} }
}
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
uint64_t id) { uint64_t id) {
@ -2617,6 +2637,36 @@ void grpc_chttp2_config_default_keepalive_args(grpc_channel_args *args,
&args->args[i], &args->args[i],
(grpc_integer_options){g_default_keepalive_permit_without_calls, (grpc_integer_options){g_default_keepalive_permit_without_calls,
0, 1}); 0, 1});
} else if (0 ==
strcmp(args->args[i].key, GRPC_ARG_HTTP2_MAX_PING_STRIKES)) {
g_default_max_ping_strikes = grpc_channel_arg_get_integer(
&args->args[i],
(grpc_integer_options){g_default_max_ping_strikes, 0, INT_MAX});
} else if (0 == strcmp(args->args[i].key,
GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) {
g_default_max_pings_without_data = grpc_channel_arg_get_integer(
&args->args[i], (grpc_integer_options){
g_default_max_pings_without_data, 0, INT_MAX});
} else if (0 ==
strcmp(
args->args[i].key,
GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS)) {
g_default_min_sent_ping_interval_without_data_ms =
grpc_channel_arg_get_integer(
&args->args[i],
(grpc_integer_options){
g_default_min_sent_ping_interval_without_data_ms, 0,
INT_MAX});
} else if (0 ==
strcmp(
args->args[i].key,
GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS)) {
g_default_min_recv_ping_interval_without_data_ms =
grpc_channel_arg_get_integer(
&args->args[i],
(grpc_integer_options){
g_default_min_recv_ping_interval_without_data_ms, 0,
INT_MAX});
} }
} }
} }

@ -92,7 +92,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec next_allowed_ping = gpr_timespec next_allowed_ping =
gpr_time_add(t->ping_recv_state.last_ping_recv_time, gpr_time_add(t->ping_recv_state.last_ping_recv_time,
t->ping_policy.min_ping_interval_without_data); t->ping_policy.min_recv_ping_interval_without_data);
if (t->keepalive_permit_without_calls == 0 && if (t->keepalive_permit_without_calls == 0 &&
grpc_chttp2_stream_map_size(&t->stream_map) == 0) { grpc_chttp2_stream_map_size(&t->stream_map) == 0) {

@ -105,10 +105,10 @@ typedef struct {
} grpc_chttp2_ping_queue; } grpc_chttp2_ping_queue;
typedef struct { typedef struct {
gpr_timespec min_time_between_pings;
int max_pings_without_data; int max_pings_without_data;
int max_ping_strikes; int max_ping_strikes;
gpr_timespec min_ping_interval_without_data; gpr_timespec min_sent_ping_interval_without_data;
gpr_timespec min_recv_ping_interval_without_data;
} grpc_chttp2_repeated_ping_policy; } grpc_chttp2_repeated_ping_policy;
typedef struct { typedef struct {

@ -383,6 +383,9 @@ error_handler:
/* t->parser = grpc_chttp2_data_parser_parse;*/ /* t->parser = grpc_chttp2_data_parser_parse;*/
t->parser = grpc_chttp2_data_parser_parse; t->parser = grpc_chttp2_data_parser_parse;
t->parser_data = &s->data_parser; t->parser_data = &s->data_parser;
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
t->ping_state.last_ping_sent_time = gpr_inf_past(GPR_CLOCK_MONOTONIC);
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) {
/* handle stream errors by closing the stream */ /* handle stream errors by closing the stream */
@ -559,6 +562,10 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx,
(t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0;
} }
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
t->ping_state.last_ping_sent_time = gpr_inf_past(GPR_CLOCK_MONOTONIC);
/* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */ /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */
s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
if (s == NULL) { if (s == NULL) {

@ -59,7 +59,7 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
} }
if (t->ping_state.pings_before_data_required == 0 && if (t->ping_state.pings_before_data_required == 0 &&
t->ping_policy.max_pings_without_data != 0) { t->ping_policy.max_pings_without_data != 0) {
/* need to send something of substance before sending a ping again */ /* need to receive something of substance before sending a ping again */
if (GRPC_TRACER_ON(grpc_http_trace) || if (GRPC_TRACER_ON(grpc_http_trace) ||
GRPC_TRACER_ON(grpc_bdp_estimator_trace)) { GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
gpr_log(GPR_DEBUG, "Ping delayed [%p]: too many recent pings: %d/%d", gpr_log(GPR_DEBUG, "Ping delayed [%p]: too many recent pings: %d/%d",
@ -69,11 +69,18 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
return; return;
} }
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec elapsed = gpr_time_sub(now, t->ping_state.last_ping_sent_time); gpr_timespec next_allowed_ping =
/*gpr_log(GPR_DEBUG, "elapsed:%d.%09d min:%d.%09d", (int)elapsed.tv_sec, gpr_time_add(t->ping_state.last_ping_sent_time,
elapsed.tv_nsec, (int)t->ping_policy.min_time_between_pings.tv_sec, t->ping_policy.min_sent_ping_interval_without_data);
(int)t->ping_policy.min_time_between_pings.tv_nsec);*/ if (t->keepalive_permit_without_calls == 0 &&
if (gpr_time_cmp(elapsed, t->ping_policy.min_time_between_pings) < 0) { grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
next_allowed_ping = gpr_time_add(t->ping_recv_state.last_ping_recv_time,
gpr_time_from_seconds(7200, GPR_TIMESPAN));
}
/* gpr_log(GPR_DEBUG, "next_allowed_ping:%d.%09d now:%d.%09d",
(int)next_allowed_ping.tv_sec, (int)next_allowed_ping.tv_nsec,
(int)now.tv_sec, (int)now.tv_nsec); */
if (gpr_time_cmp(next_allowed_ping, now) > 0) {
/* not enough elapsed time between successive pings */ /* not enough elapsed time between successive pings */
if (GRPC_TRACER_ON(grpc_http_trace) || if (GRPC_TRACER_ON(grpc_http_trace) ||
GRPC_TRACER_ON(grpc_bdp_estimator_trace)) { GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
@ -84,9 +91,7 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
if (!t->ping_state.is_delayed_ping_timer_set) { if (!t->ping_state.is_delayed_ping_timer_set) {
t->ping_state.is_delayed_ping_timer_set = true; t->ping_state.is_delayed_ping_timer_set = true;
grpc_timer_init(exec_ctx, &t->ping_state.delayed_ping_timer, grpc_timer_init(exec_ctx, &t->ping_state.delayed_ping_timer,
gpr_time_add(t->ping_state.last_ping_sent_time, next_allowed_ping, &t->retry_initiate_ping_locked,
t->ping_policy.min_time_between_pings),
&t->retry_initiate_ping_locked,
gpr_now(GPR_CLOCK_MONOTONIC)); gpr_now(GPR_CLOCK_MONOTONIC));
} }
return; return;
@ -100,6 +105,12 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
grpc_chttp2_ping_create(false, pq->inflight_id)); grpc_chttp2_ping_create(false, pq->inflight_id));
GRPC_STATS_INC_HTTP2_PINGS_SENT(exec_ctx); GRPC_STATS_INC_HTTP2_PINGS_SENT(exec_ctx);
t->ping_state.last_ping_sent_time = now; t->ping_state.last_ping_sent_time = now;
if (GRPC_TRACER_ON(grpc_http_trace) ||
GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
gpr_log(GPR_DEBUG, "Ping sent [%p]: %d/%d", t->peer_string,
t->ping_state.pings_before_data_required,
t->ping_policy.max_pings_without_data);
}
t->ping_state.pings_before_data_required -= t->ping_state.pings_before_data_required -=
(t->ping_state.pings_before_data_required != 0); (t->ping_state.pings_before_data_required != 0);
} }
@ -263,8 +274,7 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
.stats = &s->stats.outgoing}; .stats = &s->stats.outgoing};
grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor, NULL, 0, grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor, NULL, 0,
s->send_initial_metadata, &hopt, &t->outbuf); s->send_initial_metadata, &hopt, &t->outbuf);
t->ping_state.pings_before_data_required = now_writing = true;
t->ping_policy.max_pings_without_data;
if (!t->is_client) { if (!t->is_client) {
t->ping_recv_state.last_ping_recv_time = t->ping_recv_state.last_ping_recv_time =
gpr_inf_past(GPR_CLOCK_MONOTONIC); gpr_inf_past(GPR_CLOCK_MONOTONIC);
@ -303,8 +313,6 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
grpc_slice_buffer_add( grpc_slice_buffer_add(
&t->outbuf, grpc_chttp2_window_update_create(s->id, stream_announce, &t->outbuf, grpc_chttp2_window_update_create(s->id, stream_announce,
&s->stats.outgoing)); &s->stats.outgoing));
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (!t->is_client) { if (!t->is_client) {
t->ping_recv_state.last_ping_recv_time = t->ping_recv_state.last_ping_recv_time =
gpr_inf_past(GPR_CLOCK_MONOTONIC); gpr_inf_past(GPR_CLOCK_MONOTONIC);
@ -381,8 +389,6 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
send_bytes); send_bytes);
s->sending_bytes += send_bytes; s->sending_bytes += send_bytes;
} }
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (!t->is_client) { if (!t->is_client) {
t->ping_recv_state.last_ping_recv_time = t->ping_recv_state.last_ping_recv_time =
gpr_inf_past(GPR_CLOCK_MONOTONIC); gpr_inf_past(GPR_CLOCK_MONOTONIC);
@ -495,8 +501,6 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
grpc_slice_buffer_add( grpc_slice_buffer_add(
&t->outbuf, grpc_chttp2_window_update_create(0, transport_announce, &t->outbuf, grpc_chttp2_window_update_create(0, transport_announce,
&throwaway_stats)); &throwaway_stats));
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (!t->is_client) { if (!t->is_client) {
t->ping_recv_state.last_ping_recv_time = t->ping_recv_state.last_ping_recv_time =
gpr_inf_past(GPR_CLOCK_MONOTONIC); gpr_inf_past(GPR_CLOCK_MONOTONIC);

@ -519,7 +519,7 @@ static grpc_channel *create_client(const servers_fixture *f) {
arg_array[1].key = GRPC_ARG_LB_POLICY_NAME; arg_array[1].key = GRPC_ARG_LB_POLICY_NAME;
arg_array[1].value.string = "ROUND_ROBIN"; arg_array[1].value.string = "ROUND_ROBIN";
arg_array[2].type = GRPC_ARG_INTEGER; arg_array[2].type = GRPC_ARG_INTEGER;
arg_array[2].key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS; arg_array[2].key = GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS;
arg_array[2].value.integer = 0; arg_array[2].value.integer = 0;
args.num_args = GPR_ARRAY_SIZE(arg_array); args.num_args = GPR_ARRAY_SIZE(arg_array);
args.args = arg_array; args.args = arg_array;

@ -66,18 +66,19 @@ static void end_test(grpc_end2end_test_fixture *f) {
static void test_bad_ping(grpc_end2end_test_config config) { static void test_bad_ping(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL); grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq); cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_arg client_a[] = {{.type = GRPC_ARG_INTEGER, grpc_arg client_a[] = {
.key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS, {.type = GRPC_ARG_INTEGER,
.value.integer = 0}, .key = GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS,
.value.integer = 10},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, .key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA,
.value.integer = 20}, .value.integer = 0},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_BDP_PROBE, .key = GRPC_ARG_HTTP2_BDP_PROBE,
.value.integer = 0}}; .value.integer = 0}};
grpc_arg server_a[] = { grpc_arg server_a[] = {
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS, .key = GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
.value.integer = 300000 /* 5 minutes */}, .value.integer = 300000 /* 5 minutes */},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MAX_PING_STRIKES, .key = GRPC_ARG_HTTP2_MAX_PING_STRIKES,

@ -37,15 +37,19 @@ static void test_ping(grpc_end2end_test_config config,
grpc_connectivity_state state = GRPC_CHANNEL_IDLE; grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
int i; int i;
grpc_arg client_a[] = {{.type = GRPC_ARG_INTEGER, grpc_arg client_a[] = {
.key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS, {.type = GRPC_ARG_INTEGER,
.value.integer = 0}, .key = GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS,
.value.integer = 10},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, .key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA,
.value.integer = 20}}; .value.integer = 0},
{.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS,
.value.integer = 1}};
grpc_arg server_a[] = { grpc_arg server_a[] = {
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MIN_PING_INTERVAL_WITHOUT_DATA_MS, .key = GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
.value.integer = 0}, .value.integer = 0},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, .key = GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS,

@ -27,6 +27,18 @@
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"
extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
static int g_clock = 0;
static gpr_timespec fake_gpr_now(gpr_clock_type clock_type) {
return (gpr_timespec){
.tv_sec = g_clock, .tv_nsec = 0, .clock_type = clock_type,
};
}
static void inc_time(void) { g_clock += 30; }
static void test_noop(void) { static void test_noop(void) {
gpr_log(GPR_INFO, "test_noop"); gpr_log(GPR_INFO, "test_noop");
grpc_bdp_estimator est; grpc_bdp_estimator est;
@ -44,6 +56,7 @@ static void test_get_estimate_no_samples(void) {
static void add_samples(grpc_bdp_estimator *estimator, int64_t *samples, static void add_samples(grpc_bdp_estimator *estimator, int64_t *samples,
size_t n) { size_t n) {
grpc_bdp_estimator_add_incoming_bytes(estimator, 1234567); grpc_bdp_estimator_add_incoming_bytes(estimator, 1234567);
inc_time();
GPR_ASSERT(grpc_bdp_estimator_need_ping(estimator) == true); GPR_ASSERT(grpc_bdp_estimator_need_ping(estimator) == true);
grpc_bdp_estimator_schedule_ping(estimator); grpc_bdp_estimator_schedule_ping(estimator);
grpc_bdp_estimator_start_ping(estimator); grpc_bdp_estimator_start_ping(estimator);
@ -130,6 +143,7 @@ static void test_get_estimate_random_values(size_t n) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
grpc_test_init(argc, argv); grpc_test_init(argc, argv);
gpr_now_impl = fake_gpr_now;
grpc_init(); grpc_init();
test_noop(); test_noop();
test_get_estimate_no_samples(); test_get_estimate_no_samples();

Loading…
Cancel
Save