Merge pull request #8402 from muxi/backport_8235

Backport to v1.0.x: Make initial connect retry backoff configurable
pull/8426/head
Muxi Yan 8 years ago committed by GitHub
commit 3dde6d9d79
  1. 3
      include/grpc/impl/codegen/grpc_types.h
  2. 54
      src/core/ext/client_config/subchannel.c
  3. 18
      src/core/lib/channel/channel_args.c
  4. 8
      src/core/lib/channel/channel_args.h
  5. 2
      src/objective-c/GRPCClient/private/GRPCHost.m

@ -153,6 +153,9 @@ typedef struct {
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
/** The maximum time between subsequent connection attempts, in ms */
#define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms"
/** The time between the first and second connection attempts, in ms */
#define GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS \
"grpc.initial_reconnect_backoff_ms"
/* The caller of the secure_channel_create functions may override the target
name used for SSL host name checking using this channel argument which is of
type \a GRPC_ARG_STRING. This *should* be used for testing only.

@ -33,6 +33,7 @@
#include "src/core/ext/client_config/subchannel.h"
#include <limits.h>
#include <string.h>
#include <grpc/support/alloc.h>
@ -331,41 +332,40 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
grpc_closure_init(&c->connected, subchannel_connected, c);
grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
"subchannel");
gpr_backoff_init(&c->backoff_state,
GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
GRPC_SUBCHANNEL_RECONNECT_JITTER,
GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000,
GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
int initial_backoff_ms =
GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000;
int max_backoff_ms = GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000;
bool fixed_reconnect_backoff = false;
if (c->args) {
for (size_t i = 0; i < c->args->num_args; i++) {
if (0 == strcmp(c->args->args[i].key,
"grpc.testing.fixed_reconnect_backoff")) {
GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
gpr_backoff_init(&c->backoff_state, 1.0, 0.0,
c->args->args[i].value.integer,
c->args->args[i].value.integer);
}
if (0 ==
strcmp(c->args->args[i].key, GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)) {
if (c->args->args[i].type == GRPC_ARG_INTEGER) {
if (c->args->args[i].value.integer >= 0) {
gpr_backoff_init(
&c->backoff_state, GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
GRPC_SUBCHANNEL_RECONNECT_JITTER,
GPR_MIN(c->args->args[i].value.integer,
GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000),
c->args->args[i].value.integer);
} else {
gpr_log(GPR_ERROR, GRPC_ARG_MAX_RECONNECT_BACKOFF_MS
" : must be non-negative");
}
} else {
gpr_log(GPR_ERROR,
GRPC_ARG_MAX_RECONNECT_BACKOFF_MS " : must be an integer");
}
fixed_reconnect_backoff = true;
initial_backoff_ms = max_backoff_ms = grpc_channel_arg_get_integer(
&c->args->args[i],
(grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
} else if (0 == strcmp(c->args->args[i].key,
GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)) {
fixed_reconnect_backoff = false;
max_backoff_ms = grpc_channel_arg_get_integer(
&c->args->args[i],
(grpc_integer_options){max_backoff_ms, 100, INT_MAX});
} else if (0 == strcmp(c->args->args[i].key,
GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS)) {
fixed_reconnect_backoff = false;
initial_backoff_ms = grpc_channel_arg_get_integer(
&c->args->args[i],
(grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
}
}
}
gpr_backoff_init(
&c->backoff_state,
fixed_reconnect_backoff ? 1.0
: GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
fixed_reconnect_backoff ? 0.0 : GRPC_SUBCHANNEL_RECONNECT_JITTER,
initial_backoff_ms, max_backoff_ms);
gpr_mu_init(&c->mu);
return grpc_subchannel_index_register(exec_ctx, key, c);

@ -271,3 +271,21 @@ int grpc_channel_args_compare(const grpc_channel_args *a,
}
return 0;
}
int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options) {
if (arg->type != GRPC_ARG_INTEGER) {
gpr_log(GPR_ERROR, "%s ignored: it must be an integer", arg->key);
return options.default_value;
}
if (arg->value.integer < options.min_value) {
gpr_log(GPR_ERROR, "%s ignored: it must be >= %d", arg->key,
options.min_value);
return options.default_value;
}
if (arg->value.integer > options.max_value) {
gpr_log(GPR_ERROR, "%s ignored: it must be <= %d", arg->key,
options.max_value);
return options.default_value;
}
return arg->value.integer;
}

@ -87,4 +87,12 @@ uint32_t grpc_channel_args_compression_algorithm_get_states(
int grpc_channel_args_compare(const grpc_channel_args *a,
const grpc_channel_args *b);
typedef struct grpc_integer_options {
int default_value; // Return this if value is outside of expected bounds.
int min_value;
int max_value;
} grpc_integer_options;
/** Returns the value of \a arg, subject to the contraints in \a options. */
int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options);
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */

@ -219,6 +219,8 @@ static NSMutableDictionary *kHostCache;
if (_responseSizeLimitOverride) {
args[@GRPC_ARG_MAX_MESSAGE_LENGTH] = _responseSizeLimitOverride;
}
// Use 10000ms initial backoff time for correct behavior on bad/slow networks
args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = @10000;
return args;
}

Loading…
Cancel
Save