Skip to content

Commit

Permalink
Implement DnsCacheTtl accessors (#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
carterkozak authored Apr 30, 2024
1 parent e8d2171 commit ba6fb99
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 1 deletion.
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-309.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: improvement
improvement:
description: Implement DnsCacheTtl accessors
links:
- https://github.com/palantir/jvm-diagnostics/pull/309
5 changes: 4 additions & 1 deletion jvm-diagnostics/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ dependencies {
}

moduleJvmArgs {
exports 'java.management/sun.management', 'java.base/jdk.internal.platform'
exports 'java.management/sun.management',
'java.base/jdk.internal.platform',
// Required for access to 'sun.net.InetAddressCachePolicy' for DNS cache TTL
'java.base/sun.net'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.jvm.diagnostics;

public interface DnsCacheTtlAccessor {

/** Returns the number of seconds successful DNS results are cached before making another DNS request. */
int getPositiveSeconds();

/** Returns the number of seconds unsuccessful DNS results are cached before making another DNS request. */
int getNegativeSeconds();

/**
* The amount of time a previously successful DNS result will be used beyond {@link #getPositiveSeconds()} if
* subsequent DNS requests for the same hostname fail.
* Introduced in Java 21 by <a href=https://bugs.openjdk.org/browse/JDK-8306653>JDK-8306653</a>.
*/
int getStaleSeconds();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.palantir.jvm.diagnostics;

import java.lang.reflect.Method;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.function.IntSupplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -122,6 +124,20 @@ public static Optional<CpuSharesAccessor> cpuShares() {
}
}

/**
* Returns a {@link HotspotDnsCacheTtlAccessor}. This functionality is not supported on all java runtimes,
* and an {@link Optional#empty()} is returned in cases TTL information is not accessible.
*/
public static Optional<DnsCacheTtlAccessor> dnsCacheTtl() {
try {
HotspotDnsCacheTtlAccessor accessor = new HotspotDnsCacheTtlAccessor();
return accessor.isEnabled() ? Optional.of(accessor) : Optional.empty();
} catch (Throwable t) {
log.debug("Failed to create a HotspotDnsCacheTtlAccessor", t);
return Optional.empty();
}
}

private JvmDiagnostics() {}

private static final class HotspotSafepointTimeAccessor implements SafepointTimeAccessor {
Expand Down Expand Up @@ -209,4 +225,54 @@ public OptionalLong getCpuShares() {
return OptionalLong.of(result);
}
}

private static final class HotspotDnsCacheTtlAccessor implements DnsCacheTtlAccessor {

boolean isEnabled() {
try {
// Ensure invocations succeed. If sufficient exports aren't present, this will throw.
getPositiveSeconds();
return true;
} catch (Throwable t) {
return false;
}
}

private final IntSupplier staleAccessor = createStaleAccessor();

private static IntSupplier createStaleAccessor() {
if (Runtime.version().feature() >= 21) {
// Introduced in Java 21 by https://bugs.openjdk.org/browse/JDK-8306653
try {
Method getStale = sun.net.InetAddressCachePolicy.class.getMethod("getStale");
return () -> {
try {
return (Integer) getStale.invoke(null);
} catch (ReflectiveOperationException roe) {
log.debug("Failed to load stale InetAddressCachePolicy", roe);
return 0;
}
};
} catch (ReflectiveOperationException roe) {
log.debug("Failed to load stale InetAddressCachePolicy", roe);
}
}
return () -> 0;
}

@Override
public int getPositiveSeconds() {
return sun.net.InetAddressCachePolicy.get();
}

@Override
public int getNegativeSeconds() {
return sun.net.InetAddressCachePolicy.getNegative();
}

@Override
public int getStaleSeconds() {
return staleAccessor.getAsInt();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,11 @@ void testThreadUserTime() {
.getUserTimeNanoseconds(Thread.currentThread().getId()))
.isGreaterThan(0L);
}

@Test
void testDnsCacheTtl() {
assertThat(JvmDiagnostics.dnsCacheTtl().get().getPositiveSeconds()).isEqualTo(30);
assertThat(JvmDiagnostics.dnsCacheTtl().get().getNegativeSeconds()).isEqualTo(10);
assertThat(JvmDiagnostics.dnsCacheTtl().get().getStaleSeconds()).isEqualTo(0);
}
}

0 comments on commit ba6fb99

Please sign in to comment.