|
|
|
@ -78,8 +78,8 @@ class AresDnsResolver : public Resolver { |
|
|
|
|
|
|
|
|
|
static void OnNextResolution(void* arg, grpc_error* error); |
|
|
|
|
static void OnResolved(void* arg, grpc_error* error); |
|
|
|
|
static void OnNextResolutionLocked(void* arg, grpc_error* error); |
|
|
|
|
static void OnResolvedLocked(void* arg, grpc_error* error); |
|
|
|
|
void OnNextResolutionLocked(grpc_error* error); |
|
|
|
|
void OnResolvedLocked(grpc_error* error); |
|
|
|
|
|
|
|
|
|
/// DNS server to use (if not system default)
|
|
|
|
|
char* dns_server_; |
|
|
|
@ -128,6 +128,10 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args) |
|
|
|
|
.set_multiplier(GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER) |
|
|
|
|
.set_jitter(GRPC_DNS_RECONNECT_JITTER) |
|
|
|
|
.set_max_backoff(GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { |
|
|
|
|
// Closure Initialization
|
|
|
|
|
GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
GRPC_CLOSURE_INIT(&on_resolved_, OnResolved, this, grpc_schedule_on_exec_ctx); |
|
|
|
|
// Get name to resolve from URI path.
|
|
|
|
|
const char* path = args.uri->path; |
|
|
|
|
if (path[0] == '/') ++path; |
|
|
|
@ -201,28 +205,26 @@ void AresDnsResolver::ShutdownLocked() { |
|
|
|
|
|
|
|
|
|
void AresDnsResolver::OnNextResolution(void* arg, grpc_error* error) { |
|
|
|
|
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg); |
|
|
|
|
r->logical_thread()->Run( |
|
|
|
|
Closure::ToFunction(GRPC_CLOSURE_INIT(&r->on_next_resolution_, |
|
|
|
|
OnNextResolutionLocked, r, nullptr), |
|
|
|
|
GRPC_ERROR_REF(error)), |
|
|
|
|
GRPC_ERROR_REF(error); // ref owned by lambda
|
|
|
|
|
r->logical_thread()->Run([r, error]() { r->OnNextResolutionLocked(error); }, |
|
|
|
|
DEBUG_LOCATION); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { |
|
|
|
|
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg); |
|
|
|
|
void AresDnsResolver::OnNextResolutionLocked(grpc_error* error) { |
|
|
|
|
GRPC_CARES_TRACE_LOG( |
|
|
|
|
"resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: " |
|
|
|
|
"%d", |
|
|
|
|
r, grpc_error_string(error), r->shutdown_initiated_); |
|
|
|
|
r->have_next_resolution_timer_ = false; |
|
|
|
|
if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) { |
|
|
|
|
if (!r->resolving_) { |
|
|
|
|
this, grpc_error_string(error), shutdown_initiated_); |
|
|
|
|
have_next_resolution_timer_ = false; |
|
|
|
|
if (error == GRPC_ERROR_NONE && !shutdown_initiated_) { |
|
|
|
|
if (!resolving_) { |
|
|
|
|
GRPC_CARES_TRACE_LOG( |
|
|
|
|
"resolver:%p start resolving due to re-resolution timer", r); |
|
|
|
|
r->StartResolvingLocked(); |
|
|
|
|
"resolver:%p start resolving due to re-resolution timer", this); |
|
|
|
|
StartResolvingLocked(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
r->Unref(DEBUG_LOCATION, "next_resolution_timer"); |
|
|
|
|
Unref(DEBUG_LOCATION, "next_resolution_timer"); |
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool ValueInJsonArray(grpc_json* array, const char* value) { |
|
|
|
@ -327,75 +329,71 @@ char* ChooseServiceConfig(char* service_config_choice_json, |
|
|
|
|
|
|
|
|
|
void AresDnsResolver::OnResolved(void* arg, grpc_error* error) { |
|
|
|
|
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg); |
|
|
|
|
r->logical_thread()->Run( |
|
|
|
|
Closure::ToFunction( |
|
|
|
|
GRPC_CLOSURE_INIT(&r->on_resolved_, OnResolvedLocked, r, nullptr), |
|
|
|
|
GRPC_ERROR_REF(error)), |
|
|
|
|
GRPC_ERROR_REF(error); // ref owned by lambda
|
|
|
|
|
r->logical_thread()->Run([r, error]() { r->OnResolvedLocked(error); }, |
|
|
|
|
DEBUG_LOCATION); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { |
|
|
|
|
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg); |
|
|
|
|
GPR_ASSERT(r->resolving_); |
|
|
|
|
r->resolving_ = false; |
|
|
|
|
gpr_free(r->pending_request_); |
|
|
|
|
r->pending_request_ = nullptr; |
|
|
|
|
if (r->shutdown_initiated_) { |
|
|
|
|
r->Unref(DEBUG_LOCATION, "OnResolvedLocked() shutdown"); |
|
|
|
|
void AresDnsResolver::OnResolvedLocked(grpc_error* error) { |
|
|
|
|
GPR_ASSERT(resolving_); |
|
|
|
|
resolving_ = false; |
|
|
|
|
gpr_free(pending_request_); |
|
|
|
|
pending_request_ = nullptr; |
|
|
|
|
if (shutdown_initiated_) { |
|
|
|
|
Unref(DEBUG_LOCATION, "OnResolvedLocked() shutdown"); |
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (r->addresses_ != nullptr) { |
|
|
|
|
if (addresses_ != nullptr) { |
|
|
|
|
Result result; |
|
|
|
|
result.addresses = std::move(*r->addresses_); |
|
|
|
|
if (r->service_config_json_ != nullptr) { |
|
|
|
|
result.addresses = std::move(*addresses_); |
|
|
|
|
if (service_config_json_ != nullptr) { |
|
|
|
|
char* service_config_string = ChooseServiceConfig( |
|
|
|
|
r->service_config_json_, &result.service_config_error); |
|
|
|
|
gpr_free(r->service_config_json_); |
|
|
|
|
service_config_json_, &result.service_config_error); |
|
|
|
|
gpr_free(service_config_json_); |
|
|
|
|
if (result.service_config_error == GRPC_ERROR_NONE && |
|
|
|
|
service_config_string != nullptr) { |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", |
|
|
|
|
r, service_config_string); |
|
|
|
|
this, service_config_string); |
|
|
|
|
result.service_config = ServiceConfig::Create( |
|
|
|
|
service_config_string, &result.service_config_error); |
|
|
|
|
} |
|
|
|
|
gpr_free(service_config_string); |
|
|
|
|
} |
|
|
|
|
result.args = grpc_channel_args_copy(r->channel_args_); |
|
|
|
|
r->result_handler()->ReturnResult(std::move(result)); |
|
|
|
|
r->addresses_.reset(); |
|
|
|
|
result.args = grpc_channel_args_copy(channel_args_); |
|
|
|
|
result_handler()->ReturnResult(std::move(result)); |
|
|
|
|
addresses_.reset(); |
|
|
|
|
// Reset backoff state so that we start from the beginning when the
|
|
|
|
|
// next request gets triggered.
|
|
|
|
|
r->backoff_.Reset(); |
|
|
|
|
backoff_.Reset(); |
|
|
|
|
} else { |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", this, |
|
|
|
|
grpc_error_string(error)); |
|
|
|
|
r->result_handler()->ReturnError(grpc_error_set_int( |
|
|
|
|
result_handler()->ReturnError(grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"DNS resolution failed", &error, 1), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
// Set retry timer.
|
|
|
|
|
grpc_millis next_try = r->backoff_.NextAttemptTime(); |
|
|
|
|
grpc_millis next_try = backoff_.NextAttemptTime(); |
|
|
|
|
grpc_millis timeout = next_try - ExecCtx::Get()->Now(); |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s", |
|
|
|
|
r, grpc_error_string(error)); |
|
|
|
|
GPR_ASSERT(!r->have_next_resolution_timer_); |
|
|
|
|
r->have_next_resolution_timer_ = true; |
|
|
|
|
this, grpc_error_string(error)); |
|
|
|
|
GPR_ASSERT(!have_next_resolution_timer_); |
|
|
|
|
have_next_resolution_timer_ = true; |
|
|
|
|
// TODO(roth): We currently deal with this ref manually. Once the
|
|
|
|
|
// new closure API is done, find a way to track this ref with the timer
|
|
|
|
|
// callback as part of the type system.
|
|
|
|
|
r->Ref(DEBUG_LOCATION, "retry-timer").release(); |
|
|
|
|
Ref(DEBUG_LOCATION, "retry-timer").release(); |
|
|
|
|
if (timeout > 0) { |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p retrying in %" PRId64 " milliseconds", |
|
|
|
|
r, timeout); |
|
|
|
|
this, timeout); |
|
|
|
|
} else { |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p retrying immediately", r); |
|
|
|
|
GRPC_CARES_TRACE_LOG("resolver:%p retrying immediately", this); |
|
|
|
|
} |
|
|
|
|
GRPC_CLOSURE_INIT(&r->on_next_resolution_, OnNextResolution, r, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
grpc_timer_init(&r->next_resolution_timer_, next_try, |
|
|
|
|
&r->on_next_resolution_); |
|
|
|
|
grpc_timer_init(&next_resolution_timer_, next_try, &on_next_resolution_); |
|
|
|
|
} |
|
|
|
|
r->Unref(DEBUG_LOCATION, "dns-resolving"); |
|
|
|
|
Unref(DEBUG_LOCATION, "dns-resolving"); |
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AresDnsResolver::MaybeStartResolvingLocked() { |
|
|
|
@ -419,8 +417,6 @@ void AresDnsResolver::MaybeStartResolvingLocked() { |
|
|
|
|
// new closure API is done, find a way to track this ref with the timer
|
|
|
|
|
// callback as part of the type system.
|
|
|
|
|
Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); |
|
|
|
|
GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
grpc_timer_init(&next_resolution_timer_, |
|
|
|
|
ExecCtx::Get()->Now() + ms_until_next_resolution, |
|
|
|
|
&on_next_resolution_); |
|
|
|
@ -438,7 +434,6 @@ void AresDnsResolver::StartResolvingLocked() { |
|
|
|
|
GPR_ASSERT(!resolving_); |
|
|
|
|
resolving_ = true; |
|
|
|
|
service_config_json_ = nullptr; |
|
|
|
|
GRPC_CLOSURE_INIT(&on_resolved_, OnResolved, this, grpc_schedule_on_exec_ctx); |
|
|
|
|
pending_request_ = grpc_dns_lookup_ares_locked( |
|
|
|
|
dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, |
|
|
|
|
&on_resolved_, &addresses_, enable_srv_queries_ /* check_grpclb */, |
|
|
|
|