Skip to content

Commit 0675f70

Browse files
committed
core: Enable dns "caching" on Android
DnsNameResolver discards refresh requests if it has been too soon after the last refresh, because the result is assumed to be identical to the previous fetch. Android itself will adhere to the RR's TTL, so requesting too frequently shouldn't have been causing too much I/O, but it could be causing extra CPU usage. Having some lower limit will reduce the number of useless address updates into the LB tree. 30 seconds is the same as regular Java and Go/C++ (which copied Java as a "reasonable" value). Note that other languages _delay_ the refresh instead of _discarding_ the refresh, but there's no reason why the existing discard behavior would cause much problem on Android vs normal Java. Chrome apparently uses 1 minute, so this really looks like it shouldn't cause problems as long as AndroidChannelBuilder is being used.
1 parent 4de4718 commit 0675f70

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

core/src/main/java/io/grpc/internal/DnsNameResolver.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public class DnsNameResolver extends NameResolver {
100100
* not installed, the ttl value is {@code null} which falls back to {@link
101101
* #DEFAULT_NETWORK_CACHE_TTL_SECONDS gRPC default value}.
102102
*
103-
* <p>For android, gRPC doesn't attempt to cache; this property value will be ignored.
103+
* <p>For android, gRPC uses a fixed value; this property value will be ignored.
104104
*/
105105
@VisibleForTesting
106106
static final String NETWORKADDRESS_CACHE_TTL_PROPERTY = "networkaddress.cache.ttl";
@@ -451,12 +451,14 @@ private static final List<String> getHostnamesFromChoice(Map<String, ?> serviceC
451451

452452
/**
453453
* Returns value of network address cache ttl property if not Android environment. For android,
454-
* DnsNameResolver does not cache the dns lookup result.
454+
* DnsNameResolver uses a fixed value.
455455
*/
456456
private static long getNetworkAddressCacheTtlNanos(boolean isAndroid) {
457457
if (isAndroid) {
458-
// on Android, ignore dns cache.
459-
return 0;
458+
// On Android, use fixed value. If the network used changes this value shouldn't matter, as
459+
// channel.enterIdle() should be called and this name resolver instance will be discarded. The
460+
// new name resolver instance will then re-request.
461+
return TimeUnit.SECONDS.toNanos(DEFAULT_NETWORK_CACHE_TTL_SECONDS);
460462
}
461463

462464
String cacheTtlPropertyValue = System.getProperty(NETWORKADDRESS_CACHE_TTL_PROPERTY);

core/src/test/java/io/grpc/internal/DnsNameResolverTest.java

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ private RetryingNameResolver newResolver(String name, int defaultPort) {
151151
name, defaultPort, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted());
152152
}
153153

154-
private RetryingNameResolver newResolver(String name, int defaultPort, boolean isAndroid) {
155-
return newResolver(
156-
name, defaultPort, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted(),
157-
isAndroid);
158-
}
159-
160-
161154
private RetryingNameResolver newResolver(
162155
String name,
163156
int defaultPort,
@@ -227,30 +220,14 @@ public void invalidDnsName_containsUnderscore() {
227220
}
228221
}
229222

230-
@Test
231-
public void resolve_androidIgnoresPropertyValue() throws Exception {
232-
flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "2");
233-
resolveNeverCache(true);
234-
}
235-
236-
@Test
237-
public void resolve_androidIgnoresPropertyValueCacheForever() throws Exception {
238-
flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "-1");
239-
resolveNeverCache(true);
240-
}
241-
242223
@Test
243224
public void resolve_neverCache() throws Exception {
244225
flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "0");
245-
resolveNeverCache(false);
246-
}
247-
248-
private void resolveNeverCache(boolean isAndroid) throws Exception {
249226
final List<InetAddress> answer1 = createAddressList(2);
250227
final List<InetAddress> answer2 = createAddressList(1);
251228
String name = "foo.googleapis.com";
252229

253-
RetryingNameResolver resolver = newResolver(name, 81, isAndroid);
230+
RetryingNameResolver resolver = newResolver(name, 81);
254231
DnsNameResolver dnsResolver = (DnsNameResolver) resolver.getRetriedNameResolver();
255232
AddressResolver mockResolver = mock(AddressResolver.class);
256233
when(mockResolver.resolveAddress(anyString())).thenReturn(answer1).thenReturn(answer2);
@@ -443,26 +420,38 @@ public void resolve_cacheExpired() throws Exception {
443420
verify(mockResolver, times(2)).resolveAddress(anyString());
444421
}
445422

423+
@Test
424+
public void resolve_androidIgnoresPropertyValue() throws Exception {
425+
flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "2");
426+
resolveDefaultValue(true);
427+
}
428+
429+
@Test
430+
public void resolve_androidIgnoresPropertyValueCacheForever() throws Exception {
431+
flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "-1");
432+
resolveDefaultValue(true);
433+
}
434+
446435
@Test
447436
public void resolve_invalidTtlPropertyValue() throws Exception {
448437
flagResetRule.setSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY, "not_a_number");
449-
resolveDefaultValue();
438+
resolveDefaultValue(false);
450439
}
451440

452441
@Test
453442
public void resolve_noPropertyValue() throws Exception {
454443
flagResetRule.clearSystemPropertyForTest(NETWORKADDRESS_CACHE_TTL_PROPERTY);
455-
resolveDefaultValue();
444+
resolveDefaultValue(false);
456445
}
457446

458-
private void resolveDefaultValue() throws Exception {
447+
private void resolveDefaultValue(boolean isAndroid) throws Exception {
459448
final List<InetAddress> answer1 = createAddressList(2);
460449
final List<InetAddress> answer2 = createAddressList(1);
461450
String name = "foo.googleapis.com";
462451
FakeTicker fakeTicker = new FakeTicker();
463452

464453
RetryingNameResolver resolver = newResolver(
465-
name, 81, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted(fakeTicker));
454+
name, 81, GrpcUtil.NOOP_PROXY_DETECTOR, Stopwatch.createUnstarted(fakeTicker), isAndroid);
466455
DnsNameResolver dnsResolver = (DnsNameResolver) resolver.getRetriedNameResolver();
467456
AddressResolver mockResolver = mock(AddressResolver.class);
468457
when(mockResolver.resolveAddress(anyString())).thenReturn(answer1).thenReturn(answer2);

0 commit comments

Comments
 (0)