diff --git a/core/src/main/java/io/grpc/internal/DnsNameResolver.java b/core/src/main/java/io/grpc/internal/DnsNameResolver.java index dacbe291b6b..f148ddc34a8 100644 --- a/core/src/main/java/io/grpc/internal/DnsNameResolver.java +++ b/core/src/main/java/io/grpc/internal/DnsNameResolver.java @@ -100,7 +100,7 @@ public class DnsNameResolver extends NameResolver { * not installed, the ttl value is {@code null} which falls back to {@link * #DEFAULT_NETWORK_CACHE_TTL_SECONDS gRPC default value}. * - *

For android, gRPC doesn't attempt to cache; this property value will be ignored. + *

For android, gRPC uses a fixed value; this property value will be ignored. */ @VisibleForTesting static final String NETWORKADDRESS_CACHE_TTL_PROPERTY = "networkaddress.cache.ttl"; @@ -451,12 +451,14 @@ private static final List getHostnamesFromChoice(Map serviceC /** * Returns value of network address cache ttl property if not Android environment. For android, - * DnsNameResolver does not cache the dns lookup result. + * DnsNameResolver uses a fixed value. */ private static long getNetworkAddressCacheTtlNanos(boolean isAndroid) { if (isAndroid) { - // on Android, ignore dns cache. - return 0; + // On Android, use fixed value. If the network used changes this value shouldn't matter, as + // channel.enterIdle() should be called and this name resolver instance will be discarded. The + // new name resolver instance will then re-request. + return TimeUnit.SECONDS.toNanos(DEFAULT_NETWORK_CACHE_TTL_SECONDS); } String cacheTtlPropertyValue = System.getProperty(NETWORKADDRESS_CACHE_TTL_PROPERTY); diff --git a/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java b/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java index 0a46b7d8204..c4b7d605cee 100644 --- a/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java +++ b/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java @@ -151,13 +151,6 @@ private RetryingNameResolver newResolver(String name, int defaultPort) { name, defaultPort, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted()); } - private RetryingNameResolver newResolver(String name, int defaultPort, boolean isAndroid) { - return newResolver( - name, defaultPort, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted(), - isAndroid); - } - - private RetryingNameResolver newResolver( String name, int defaultPort, @@ -227,30 +220,14 @@ public void invalidDnsName_containsUnderscore() { } } - @Test - public void resolve_androidIgnoresPropertyValue() throws Exception { - flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "2"); - resolveNeverCache(true); - } - - @Test - public void resolve_androidIgnoresPropertyValueCacheForever() throws Exception { - flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "-1"); - resolveNeverCache(true); - } - @Test public void resolve_neverCache() throws Exception { flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "0"); - resolveNeverCache(false); - } - - private void resolveNeverCache(boolean isAndroid) throws Exception { final List answer1 = createAddressList(2); final List answer2 = createAddressList(1); String name = "foo.googleapis.com"; - RetryingNameResolver resolver = newResolver(name, 81, isAndroid); + RetryingNameResolver resolver = newResolver(name, 81); DnsNameResolver dnsResolver = (DnsNameResolver) resolver.getRetriedNameResolver(); AddressResolver mockResolver = mock(AddressResolver.class); when(mockResolver.resolveAddress(anyString())).thenReturn(answer1).thenReturn(answer2); @@ -443,26 +420,38 @@ public void resolve_cacheExpired() throws Exception { verify(mockResolver, times(2)).resolveAddress(anyString()); } + @Test + public void resolve_androidIgnoresPropertyValue() throws Exception { + flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "2"); + resolveDefaultValue(true); + } + + @Test + public void resolve_androidIgnoresPropertyValueCacheForever() throws Exception { + flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "-1"); + resolveDefaultValue(true); + } + @Test public void resolve_invalidTtlPropertyValue() throws Exception { flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "not_a_number"); - resolveDefaultValue(); + resolveDefaultValue(false); } @Test public void resolve_noPropertyValue() throws Exception { flagResetRule.clearSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY); - resolveDefaultValue(); + resolveDefaultValue(false); } - private void resolveDefaultValue() throws Exception { + private void resolveDefaultValue(boolean isAndroid) throws Exception { final List answer1 = createAddressList(2); final List answer2 = createAddressList(1); String name = "foo.googleapis.com"; FakeTicker fakeTicker = new FakeTicker(); RetryingNameResolver resolver = newResolver( - name, 81, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted(fakeTicker)); + name, 81, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted(fakeTicker), isAndroid); DnsNameResolver dnsResolver = (DnsNameResolver) resolver.getRetriedNameResolver(); AddressResolver mockResolver = mock(AddressResolver.class); when(mockResolver.resolveAddress(anyString())).thenReturn(answer1).thenReturn(answer2);