diff options
Diffstat (limited to 'grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc')
-rw-r--r-- | grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | 119 |
1 files changed, 59 insertions, 60 deletions
diff --git a/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 0060ad98..2911eae7 100644 --- a/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -80,10 +80,10 @@ class AresDnsResolver : public Resolver { void MaybeStartResolvingLocked(); void StartResolvingLocked(); - static void OnNextResolution(void* arg, grpc_error* error); - static void OnResolved(void* arg, grpc_error* error); - void OnNextResolutionLocked(grpc_error* error); - void OnResolvedLocked(grpc_error* error); + static void OnNextResolution(void* arg, grpc_error_handle error); + static void OnResolved(void* arg, grpc_error_handle error); + void OnNextResolutionLocked(grpc_error_handle error); + void OnResolvedLocked(grpc_error_handle error); /// DNS server to use (if not system default) std::string dns_server_; @@ -91,10 +91,20 @@ class AresDnsResolver : public Resolver { std::string name_to_resolve_; /// channel args grpc_channel_args* channel_args_; - /// whether to request the service config - bool request_service_config_; + std::shared_ptr<WorkSerializer> work_serializer_; + std::unique_ptr<ResultHandler> result_handler_; /// pollset_set to drive the name resolution process grpc_pollset_set* interested_parties_; + + /// whether to request the service config + bool request_service_config_; + // whether or not to enable SRV DNS queries + bool enable_srv_queries_; + // timeout in milliseconds for active DNS queries + int query_timeout_ms_; + /// min interval between DNS requests + grpc_millis min_time_between_resolutions_; + /// closures used by the work_serializer grpc_closure on_next_resolution_; grpc_closure on_resolved_; @@ -105,8 +115,6 @@ class AresDnsResolver : public Resolver { /// next resolution timer bool have_next_resolution_timer_ = false; grpc_timer next_resolution_timer_; - /// min interval between DNS requests - grpc_millis min_time_between_resolutions_; /// timestamp of last DNS request grpc_millis last_resolution_timestamp_ = -1; /// retry backoff state @@ -119,14 +127,25 @@ class AresDnsResolver : public Resolver { char* service_config_json_ = nullptr; // has shutdown been initiated bool shutdown_initiated_ = false; - // timeout in milliseconds for active DNS queries - int query_timeout_ms_; - // whether or not to enable SRV DNS queries - bool enable_srv_queries_; }; AresDnsResolver::AresDnsResolver(ResolverArgs args) - : Resolver(std::move(args.work_serializer), std::move(args.result_handler)), + : dns_server_(args.uri.authority()), + name_to_resolve_(absl::StripPrefix(args.uri.path(), "/")), + channel_args_(grpc_channel_args_copy(args.args)), + work_serializer_(std::move(args.work_serializer)), + result_handler_(std::move(args.result_handler)), + interested_parties_(args.pollset_set), + request_service_config_(!grpc_channel_args_find_bool( + channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, true)), + enable_srv_queries_(grpc_channel_args_find_bool( + channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES, false)), + query_timeout_ms_(grpc_channel_args_find_integer( + channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS, + {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX})), + min_time_between_resolutions_(grpc_channel_args_find_integer( + channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS, + {1000 * 30, 0, INT_MAX})), backoff_( BackOff::Options() .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * @@ -134,42 +153,14 @@ 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 + // 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. - name_to_resolve_ = std::string(absl::StripPrefix(args.uri.path(), "/")); - // Get DNS server from URI authority. - dns_server_ = args.uri.authority(); - channel_args_ = grpc_channel_args_copy(args.args); - // Disable service config option - const grpc_arg* arg = grpc_channel_args_find( - channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION); - request_service_config_ = !grpc_channel_arg_get_bool(arg, true); - // Min time b/t resolutions option - arg = grpc_channel_args_find(channel_args_, - GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); - min_time_between_resolutions_ = - grpc_channel_arg_get_integer(arg, {1000 * 30, 0, INT_MAX}); - // Enable SRV queries option - arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES); - enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false); - interested_parties_ = grpc_pollset_set_create(); - if (args.pollset_set != nullptr) { - grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set); - } - - const grpc_arg* query_timeout_ms_arg = - grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); - query_timeout_ms_ = grpc_channel_arg_get_integer( - query_timeout_ms_arg, - {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX}); } AresDnsResolver::~AresDnsResolver() { GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this); - grpc_pollset_set_destroy(interested_parties_); grpc_channel_args_destroy(channel_args_); } @@ -202,18 +193,18 @@ void AresDnsResolver::ShutdownLocked() { } } -void AresDnsResolver::OnNextResolution(void* arg, grpc_error* error) { +void AresDnsResolver::OnNextResolution(void* arg, grpc_error_handle error) { AresDnsResolver* r = static_cast<AresDnsResolver*>(arg); GRPC_ERROR_REF(error); // ref owned by lambda - r->work_serializer()->Run([r, error]() { r->OnNextResolutionLocked(error); }, - DEBUG_LOCATION); + r->work_serializer_->Run([r, error]() { r->OnNextResolutionLocked(error); }, + DEBUG_LOCATION); } -void AresDnsResolver::OnNextResolutionLocked(grpc_error* error) { +void AresDnsResolver::OnNextResolutionLocked(grpc_error_handle error) { GRPC_CARES_TRACE_LOG( "resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: " "%d", - this, grpc_error_string(error), shutdown_initiated_); + this, grpc_error_std_string(error).c_str(), shutdown_initiated_); have_next_resolution_timer_ = false; if (error == GRPC_ERROR_NONE && !shutdown_initiated_) { if (!resolving_) { @@ -236,7 +227,7 @@ bool ValueInJsonArray(const Json::Array& array, const char* value) { } std::string ChooseServiceConfig(char* service_config_choice_json, - grpc_error** error) { + grpc_error_handle* error) { Json json = Json::Parse(service_config_choice_json, error); if (*error != GRPC_ERROR_NONE) return ""; if (json.type() != Json::Type::ARRAY) { @@ -245,7 +236,7 @@ std::string ChooseServiceConfig(char* service_config_choice_json, return ""; } const Json* service_config = nullptr; - absl::InlinedVector<grpc_error*, 4> error_list; + absl::InlinedVector<grpc_error_handle, 4> error_list; for (const Json& choice : json.array_value()) { if (choice.type() != Json::Type::OBJECT) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -314,14 +305,14 @@ std::string ChooseServiceConfig(char* service_config_choice_json, return service_config->Dump(); } -void AresDnsResolver::OnResolved(void* arg, grpc_error* error) { +void AresDnsResolver::OnResolved(void* arg, grpc_error_handle error) { AresDnsResolver* r = static_cast<AresDnsResolver*>(arg); GRPC_ERROR_REF(error); // ref owned by lambda - r->work_serializer()->Run([r, error]() { r->OnResolvedLocked(error); }, - DEBUG_LOCATION); + r->work_serializer_->Run([r, error]() { r->OnResolvedLocked(error); }, + DEBUG_LOCATION); } -void AresDnsResolver::OnResolvedLocked(grpc_error* error) { +void AresDnsResolver::OnResolvedLocked(grpc_error_handle error) { GPR_ASSERT(resolving_); resolving_ = false; gpr_free(pending_request_); @@ -355,7 +346,7 @@ void AresDnsResolver::OnResolvedLocked(grpc_error* error) { } result.args = grpc_channel_args_copy_and_add(channel_args_, new_args.data(), new_args.size()); - result_handler()->ReturnResult(std::move(result)); + result_handler_->ReturnResult(std::move(result)); addresses_.reset(); balancer_addresses_.reset(); // Reset backoff state so that we start from the beginning when the @@ -363,18 +354,22 @@ void AresDnsResolver::OnResolvedLocked(grpc_error* error) { backoff_.Reset(); } else { GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", this, - grpc_error_string(error)); + grpc_error_std_string(error).c_str()); std::string error_message = absl::StrCat("DNS resolution failed for service: ", name_to_resolve_); - result_handler()->ReturnError(grpc_error_set_int( + result_handler_->ReturnError(grpc_error_set_int( GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(error_message.c_str(), &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); // Set retry timer. + // InvalidateNow to avoid getting stuck re-initializing this timer + // in a loop while draining the currently-held WorkSerializer. + // Also see https://github.com/grpc/grpc/issues/26079. + ExecCtx::Get()->InvalidateNow(); 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", - this, grpc_error_string(error)); + this, grpc_error_std_string(error).c_str()); GPR_ASSERT(!have_next_resolution_timer_); have_next_resolution_timer_ = true; // TODO(roth): We currently deal with this ref manually. Once the @@ -398,6 +393,10 @@ void AresDnsResolver::MaybeStartResolvingLocked() { // can start the next resolution. if (have_next_resolution_timer_) return; if (last_resolution_timestamp_ >= 0) { + // InvalidateNow to avoid getting stuck re-initializing this timer + // in a loop while draining the currently-held WorkSerializer. + // Also see https://github.com/grpc/grpc/issues/26079. + ExecCtx::Get()->InvalidateNow(); const grpc_millis earliest_next_resolution = last_resolution_timestamp_ + min_time_between_resolutions_; const grpc_millis ms_until_next_resolution = @@ -436,7 +435,7 @@ void AresDnsResolver::StartResolvingLocked() { interested_parties_, &on_resolved_, &addresses_, enable_srv_queries_ ? &balancer_addresses_ : nullptr, request_service_config_ ? &service_config_json_ : nullptr, - query_timeout_ms_, work_serializer()); + query_timeout_ms_, work_serializer_); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p", this, pending_request_); @@ -464,7 +463,7 @@ class AresDnsResolverFactory : public ResolverFactory { extern grpc_address_resolver_vtable* grpc_resolve_address_impl; static grpc_address_resolver_vtable* default_resolver; -static grpc_error* blocking_resolve_address_ares( +static grpc_error_handle blocking_resolve_address_ares( const char* name, const char* default_port, grpc_resolved_addresses** addresses) { return default_resolver->blocking_resolve_address(name, default_port, @@ -499,7 +498,7 @@ void grpc_resolver_dns_ares_init() { g_use_ares_dns_resolver = true; gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); - grpc_error* error = grpc_ares_init(); + grpc_error_handle error = grpc_ares_init(); if (error != GRPC_ERROR_NONE) { GRPC_LOG_IF_ERROR("grpc_ares_init() failed", error); return; |