diff options
author | David Garcia Quintas <dgq@google.com> | 2018-01-30 15:46:27 -0800 |
---|---|---|
committer | David Garcia Quintas <dgq@google.com> | 2018-01-30 15:46:27 -0800 |
commit | e7cd8355ea1b2856cd3826bba95edebd227a1396 (patch) | |
tree | 944ceee0005d9915f218cd0e547b0416e3a09919 /src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | |
parent | 3ee68da517f32acbba8b8f98145cd8d218f2ddd7 (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.cc | 92 |
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; } |