aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
diff options
context:
space:
mode:
authorGravatar David Garcia Quintas <dgq@google.com>2018-01-30 15:46:27 -0800
committerGravatar David Garcia Quintas <dgq@google.com>2018-01-30 15:46:27 -0800
commite7cd8355ea1b2856cd3826bba95edebd227a1396 (patch)
tree944ceee0005d9915f218cd0e547b0416e3a09919 /src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
parent3ee68da517f32acbba8b8f98145cd8d218f2ddd7 (diff)
c-ares resolver changes
Diffstat (limited to 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc')
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc92
1 files changed, 74 insertions, 18 deletions
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 6ba5f932f0..375cd743fb 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -66,7 +66,7 @@ typedef struct {
grpc_pollset_set* interested_parties;
/** Closures used by the combiner */
- grpc_closure dns_ares_on_retry_timer_locked;
+ grpc_closure dns_ares_on_next_resolution_timer_locked;
grpc_closure dns_ares_on_resolved_locked;
/** Combiner guarding the rest of the state */
@@ -86,11 +86,17 @@ typedef struct {
/** current (fully resolved) result */
grpc_channel_args* resolved_result;
/** retry timer */
- bool have_retry_timer;
- grpc_timer retry_timer;
+ bool have_next_resolution_timer;
+ grpc_timer next_resolution_timer;
/** retry backoff state */
grpc_core::ManualConstructor<grpc_core::BackOff> backoff;
-
+ /** min resolution period. Max one resolution will happen per period */
+ grpc_millis min_time_between_resolutions;
+ /** when was the last resolution? If no resolution has happened yet, equals
+ * gpr_inf_past() */
+ grpc_millis last_resolution_timestamp;
+ /** To be invoked once the cooldown period is over */
+ grpc_closure deferred_resolution_closure;
/** currently resolving addresses */
grpc_lb_addresses* lb_addresses;
/** currently resolving service config */
@@ -100,6 +106,7 @@ typedef struct {
static void dns_ares_destroy(grpc_resolver* r);
static void dns_ares_start_resolving_locked(ares_dns_resolver* r);
+static void dns_ares_maybe_start_resolving_locked(ares_dns_resolver* r);
static void dns_ares_maybe_finish_next_locked(ares_dns_resolver* r);
static void dns_ares_shutdown_locked(grpc_resolver* r);
@@ -114,8 +121,8 @@ static const grpc_resolver_vtable dns_ares_resolver_vtable = {
static void dns_ares_shutdown_locked(grpc_resolver* resolver) {
ares_dns_resolver* r = (ares_dns_resolver*)resolver;
- if (r->have_retry_timer) {
- grpc_timer_cancel(&r->retry_timer);
+ if (r->have_next_resolution_timer) {
+ grpc_timer_cancel(&r->next_resolution_timer);
}
if (r->pending_request != nullptr) {
grpc_cancel_ares_request(r->pending_request);
@@ -132,19 +139,20 @@ static void dns_ares_channel_saw_error_locked(grpc_resolver* resolver) {
ares_dns_resolver* r = (ares_dns_resolver*)resolver;
if (!r->resolving) {
r->backoff->Reset();
- dns_ares_start_resolving_locked(r);
+ dns_ares_maybe_start_resolving_locked(r);
}
}
-static void dns_ares_on_retry_timer_locked(void* arg, grpc_error* error) {
+static void dns_ares_on_next_resolution_timer_locked(void* arg,
+ grpc_error* error) {
ares_dns_resolver* r = (ares_dns_resolver*)arg;
- r->have_retry_timer = false;
+ r->have_next_resolution_timer = false;
if (error == GRPC_ERROR_NONE) {
if (!r->resolving) {
- dns_ares_start_resolving_locked(r);
+ dns_ares_maybe_start_resolving_locked(r);
}
}
- GRPC_RESOLVER_UNREF(&r->base, "retry-timer");
+ GRPC_RESOLVER_UNREF(&r->base, "next_resolution_timer");
}
static bool value_in_json_array(grpc_json* array, const char* value) {
@@ -268,21 +276,22 @@ static void dns_ares_on_resolved_locked(void* arg, grpc_error* error) {
grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
grpc_error_string(error));
- GPR_ASSERT(!r->have_retry_timer);
- r->have_retry_timer = true;
- GRPC_RESOLVER_REF(&r->base, "retry-timer");
+ GPR_ASSERT(!r->have_next_resolution_timer);
+ r->have_next_resolution_timer = true;
+ GRPC_RESOLVER_REF(&r->base, "next_resolution_timer");
if (timeout > 0) {
gpr_log(GPR_DEBUG, "retrying in %" PRIdPTR " milliseconds", timeout);
} else {
gpr_log(GPR_DEBUG, "retrying immediately");
}
- grpc_timer_init(&r->retry_timer, next_try,
- &r->dns_ares_on_retry_timer_locked);
+ grpc_timer_init(&r->next_resolution_timer, next_try,
+ &r->dns_ares_on_next_resolution_timer_locked);
}
if (r->resolved_result != nullptr) {
grpc_channel_args_destroy(r->resolved_result);
}
r->resolved_result = result;
+ r->last_resolution_timestamp = grpc_core::ExecCtx::Get()->Now();
r->resolved_version++;
dns_ares_maybe_finish_next_locked(r);
GRPC_RESOLVER_UNREF(&r->base, "dns-resolving");
@@ -330,6 +339,36 @@ static void dns_ares_maybe_finish_next_locked(ares_dns_resolver* r) {
}
}
+static void dns_ares_maybe_start_resolving_locked(ares_dns_resolver* r) {
+ gpr_log(GPR_INFO, "IN %s, LAST RESOLUTION TS: %lu", __func__,
+ r->last_resolution_timestamp);
+ if (r->last_resolution_timestamp >= 0) {
+ const grpc_millis earliest_next_resolution =
+ r->last_resolution_timestamp + r->min_time_between_resolutions;
+ const grpc_millis ms_until_next_resolution =
+ earliest_next_resolution - grpc_core::ExecCtx::Get()->Now();
+ if (ms_until_next_resolution > 0) {
+ const grpc_millis last_resolution_ago =
+ grpc_core::ExecCtx::Get()->Now() - r->last_resolution_timestamp;
+ gpr_log(
+ GPR_DEBUG,
+ "In cooldown from last resolution (from %ld ms ago). Will resolve "
+ "again in %ld ms",
+ last_resolution_ago, ms_until_next_resolution);
+ if (!r->have_next_resolution_timer) {
+ r->have_next_resolution_timer = true;
+ GRPC_RESOLVER_REF(&r->base, "next_resolution_timer_cooldown");
+ grpc_timer_init(&r->next_resolution_timer, ms_until_next_resolution,
+ &r->deferred_resolution_closure);
+ }
+ ++r->resolved_version;
+ dns_ares_maybe_finish_next_locked(r);
+ return;
+ }
+ }
+ dns_ares_start_resolving_locked(r);
+}
+
static void dns_ares_destroy(grpc_resolver* gr) {
gpr_log(GPR_DEBUG, "dns_ares_destroy");
ares_dns_resolver* r = (ares_dns_resolver*)gr;
@@ -344,6 +383,15 @@ static void dns_ares_destroy(grpc_resolver* gr) {
gpr_free(r);
}
+static void ares_cooldown_cb(void* arg, grpc_error* error) {
+ ares_dns_resolver* r = (ares_dns_resolver*)arg;
+ r->have_next_resolution_timer = false;
+ if (error == GRPC_ERROR_NONE && !r->resolving) {
+ dns_ares_start_resolving_locked(r);
+ }
+ GRPC_RESOLVER_UNREF(&r->base, "next_resolution_timer_cooldown");
+}
+
static grpc_resolver* dns_ares_create(grpc_resolver_args* args,
const char* default_port) {
/* Get name from args. */
@@ -374,12 +422,20 @@ static grpc_resolver* dns_ares_create(grpc_resolver_args* args,
.set_jitter(GRPC_DNS_RECONNECT_JITTER)
.set_max_backoff(GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
r->backoff.Init(grpc_core::BackOff(backoff_options));
- GRPC_CLOSURE_INIT(&r->dns_ares_on_retry_timer_locked,
- dns_ares_on_retry_timer_locked, r,
+ GRPC_CLOSURE_INIT(&r->dns_ares_on_next_resolution_timer_locked,
+ dns_ares_on_next_resolution_timer_locked, r,
grpc_combiner_scheduler(r->base.combiner));
GRPC_CLOSURE_INIT(&r->dns_ares_on_resolved_locked,
dns_ares_on_resolved_locked, r,
grpc_combiner_scheduler(r->base.combiner));
+ const grpc_arg* period_arg = grpc_channel_args_find(
+ args->args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
+ const grpc_millis min_time_between_resolutions =
+ grpc_channel_arg_get_integer(period_arg, {1000, 0, INT_MAX});
+ r->min_time_between_resolutions = min_time_between_resolutions;
+ r->last_resolution_timestamp = -1;
+ GRPC_CLOSURE_INIT(&r->deferred_resolution_closure, ares_cooldown_cb, r,
+ grpc_combiner_scheduler(r->base.combiner));
return &r->base;
}