Exemplo n.º 1
0
        protected override async Task ResolveAsync(CancellationToken cancellationToken)
        {
            try
            {
                var elapsedTimeSinceLastRefresh = SystemClock.UtcNow - _lastResolveStart;
                if (elapsedTimeSinceLastRefresh < MinimumDnsResolutionRate)
                {
                    var delay = MinimumDnsResolutionRate - elapsedTimeSinceLastRefresh;
                    DnsResolverLog.StartingRateLimitDelay(_logger, delay, MinimumDnsResolutionRate);

                    await Task.Delay(delay, cancellationToken).ConfigureAwait(false);
                }

                var lastResolveStart = SystemClock.UtcNow;

                if (string.IsNullOrEmpty(_dnsAddress))
                {
                    throw new InvalidOperationException($"Resolver address '{_originalAddress}' is not valid. Please use dns:/// for DNS provider.");
                }

                DnsResolverLog.StartingDnsQuery(_logger, _dnsAddress);
                var addresses =
#if NET6_0_OR_GREATER
                    await Dns.GetHostAddressesAsync(_dnsAddress, cancellationToken).ConfigureAwait(false);
#else
                    await Dns.GetHostAddressesAsync(_dnsAddress).ConfigureAwait(false);
#endif

                DnsResolverLog.ReceivedDnsResults(_logger, addresses.Length, _dnsAddress, addresses);

                var endpoints      = addresses.Select(a => new BalancerAddress(a.ToString(), _port)).ToArray();
                var resolverResult = ResolverResult.ForResult(endpoints);
                Listener(resolverResult);

                // Only update last resolve start if successful. Backoff will handle limiting resolves on failure.
                _lastResolveStart = lastResolveStart;
            }
            catch (Exception ex)
            {
                var message = $"Error getting DNS hosts for address '{_dnsAddress}'.";

                DnsResolverLog.ErrorQueryingDns(_logger, _dnsAddress, ex);
                Listener(ResolverResult.ForFailure(GrpcProtocolHelpers.CreateStatusFromException(message, ex, StatusCode.Unavailable)));
            }
        }