Fix FrontierNodeVersion multiple instantiation and add logging.
getSkyValueVersion calls were still creating multiple FrontierNodeVersion
objects, and I realized that it was missing double-checked locking in the
synchronized block.
Also remove the call to serialize a simple string repr of the active directories -- we can pass the actual byte array instead.
Also added a log line for the components of the skyvalue version for debugging.
```
241024 09:20:21.005:I 51 [com.google.devtools.build.lib.buildtool.BuildTool.buildTargets:223] Build identifier: 2d2c2b5c-1930-4d5f-86a2-759b3e3814f7
241024 09:21:26.650:I 2486 [com.google.devtools.build.lib.buildtool.BuildTool$RemoteAnalysisCachingDependenciesProviderImpl.getSkyValueVersion:1182] Remote analysis caching SkyValue version: FrontierNodeVersion{topLevelConfig=-75950329, directoryMatcher=-1987693526, blazeInstall=-542573734, precomputed=688156809}
```
PiperOrigin-RevId: 689369335
Change-Id: I0931bc6662d83b5e5a107aa541715b509be67857
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index 55ac41e..53333e1 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -1157,17 +1157,31 @@
return activeDirectoriesMatcher.includes(pkg.getPackageFragment());
}
- private FrontierNodeVersion frontierNodeVersionSingleton = null;
+ private volatile FrontierNodeVersion frontierNodeVersionSingleton = null;
+ /**
+ * Returns a byte array to uniquely version SkyValues for serialization.
+ *
+ * <p>This should only be caalled when Bazel has determined values for all version components
+ * for instantiating a {@link FrontierNodeVersion}.
+ *
+ * <p>This could be in the constructor if we know about the {@code topLevelConfig} component at
+ * initialization, but it is created much later during the deserialization pass.
+ */
@Override
- public FrontierNodeVersion getSkyValueVersion() throws SerializationException {
+ public FrontierNodeVersion getSkyValueVersion() {
if (frontierNodeVersionSingleton == null) {
synchronized (this) {
- frontierNodeVersionSingleton =
- new FrontierNodeVersion(
- topLevelConfig.checksum(),
- getObjectCodecs().serializeMemoized(activeDirectoriesMatcher.toString()),
- blazeInstallMD5);
+ // Avoid re-initializing the value for subsequent threads with double checked locking.
+ if (frontierNodeVersionSingleton == null) {
+ frontierNodeVersionSingleton =
+ new FrontierNodeVersion(
+ topLevelConfig.checksum(),
+ activeDirectoriesMatcher.toString(),
+ blazeInstallMD5);
+ logger.atInfo().log(
+ "Remote analysis caching SkyValue version: %s", frontierNodeVersionSingleton);
+ }
}
}
return frontierNodeVersionSingleton;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetriever.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetriever.java
index fff88cd..d1241f8 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetriever.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetriever.java
@@ -20,6 +20,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
import com.google.common.hash.HashCode;
import com.google.common.primitives.Bytes;
import com.google.common.util.concurrent.Futures;
@@ -328,8 +329,7 @@
/** A tuple representing the version of a cached SkyValue in the frontier. */
public static final class FrontierNodeVersion {
public static final FrontierNodeVersion CONSTANT_FOR_TESTING =
- new FrontierNodeVersion(
- "123", ByteString.copyFrom(new byte[] {1, 2, 3}), HashCode.fromInt(42));
+ new FrontierNodeVersion("123", "string_for_testing", HashCode.fromInt(42));
private final byte[] topLevelConfigFingerprint;
private final byte[] directoryMatcherFingerprint;
private final byte[] blazeInstallMD5Fingerprint;
@@ -337,11 +337,11 @@
public FrontierNodeVersion(
String topLevelConfigChecksum,
- ByteString directoryMatcherFingerprint,
+ String directoryMatcherStringRepr,
HashCode blazeInstallMD5) {
// TODO: b/364831651 - add more fields like source and blaze versions.
this.topLevelConfigFingerprint = topLevelConfigChecksum.getBytes(UTF_8);
- this.directoryMatcherFingerprint = directoryMatcherFingerprint.toByteArray();
+ this.directoryMatcherFingerprint = directoryMatcherStringRepr.getBytes(UTF_8);
this.blazeInstallMD5Fingerprint = blazeInstallMD5.asBytes();
this.precomputedFingerprint =
Bytes.concat(
@@ -359,6 +359,16 @@
}
@Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("topLevelConfig", Arrays.hashCode(topLevelConfigFingerprint))
+ .add("directoryMatcher", Arrays.hashCode(directoryMatcherFingerprint))
+ .add("blazeInstall", Arrays.hashCode(blazeInstallMD5Fingerprint))
+ .add("precomputed", hashCode())
+ .toString();
+ }
+
+ @Override
public int hashCode() {
return Arrays.hashCode(precomputedFingerprint);
}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetrieverTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetrieverTest.java
index 7e78404..ed742f5 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetrieverTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/SkyValueRetrieverTest.java
@@ -167,7 +167,7 @@
var version =
new FrontierNodeVersion(
/* topLevelConfigChecksum= */ "42",
- /* directoryMatcherFingerprint= */ ByteString.copyFrom(new byte[] {1, 2, 3}),
+ /* directoryMatcherStringRepr= */ "some_string",
/* blazeInstallMD5= */ HashCode.fromInt(42));
uploadKeyValuePair(key, version, value, fingerprintValueService);
@@ -194,7 +194,7 @@
var version =
new FrontierNodeVersion(
/* topLevelConfigChecksum= */ "42",
- /* directoryMatcherFingerprint= */ ByteString.copyFrom(new byte[] {1, 2, 3}),
+ /* directoryMatcherStringRepr= */ "some_string",
/* blazeInstallMD5= */ HashCode.fromInt(42));
uploadKeyValuePair(key, version, value, fingerprintValueService);
@@ -208,7 +208,7 @@
/* stateProvider= */ this,
/* frontierNodeVersion= */ new FrontierNodeVersion(
/* topLevelConfigChecksum= */ "9000",
- /* directoryMatcherFingerprint= */ ByteString.copyFrom(new byte[] {7, 8, 9}),
+ /* directoryMatcherStringRepr= */ "another_string",
/* blazeInstallMD5= */ HashCode.fromInt(9000)));
assertThat(result).isSameInstanceAs(NO_CACHED_DATA);
@@ -546,10 +546,8 @@
@Test
public void frontierNodeVersions_areEqual_ifTupleComponentsAreEqual() {
- var first =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("bar"), HashCode.fromInt(42));
- var second =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("bar"), HashCode.fromInt(42));
+ var first = new FrontierNodeVersion("foo", "bar", HashCode.fromInt(42));
+ var second = new FrontierNodeVersion("foo", "bar", HashCode.fromInt(42));
assertThat(first.getPrecomputedFingerprint()).isEqualTo(second.getPrecomputedFingerprint());
assertThat(first).isEqualTo(second);
@@ -557,10 +555,8 @@
@Test
public void frontierNodeVersions_areNotEqual_ifTopLevelConfigChecksumIsDifferent() {
- var first =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("bar"), HashCode.fromInt(42));
- var second =
- new FrontierNodeVersion("CHANGED", ByteString.copyFromUtf8("bar"), HashCode.fromInt(42));
+ var first = new FrontierNodeVersion("foo", "bar", HashCode.fromInt(42));
+ var second = new FrontierNodeVersion("CHANGED", "bar", HashCode.fromInt(42));
assertThat(first.getPrecomputedFingerprint()).isNotEqualTo(second.getPrecomputedFingerprint());
assertThat(first).isNotEqualTo(second);
@@ -568,10 +564,8 @@
@Test
public void frontierNodeVersions_areNotEqual_ifActiveDirectoriesAreDifferent() {
- var first =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("bar"), HashCode.fromInt(42));
- var second =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("CHANGED"), HashCode.fromInt(42));
+ var first = new FrontierNodeVersion("foo", "bar", HashCode.fromInt(42));
+ var second = new FrontierNodeVersion("foo", "CHANGED", HashCode.fromInt(42));
assertThat(first.getPrecomputedFingerprint()).isNotEqualTo(second.getPrecomputedFingerprint());
assertThat(first).isNotEqualTo(second);
@@ -579,10 +573,8 @@
@Test
public void frontierNodeVersions_areNotEqual_ifBlazeInstallMD5IsDifferent() {
- var first =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("bar"), HashCode.fromInt(42));
- var second =
- new FrontierNodeVersion("foo", ByteString.copyFromUtf8("bar"), HashCode.fromInt(9000));
+ var first = new FrontierNodeVersion("foo", "bar", HashCode.fromInt(42));
+ var second = new FrontierNodeVersion("foo", "bar", HashCode.fromInt(9000));
assertThat(first.getPrecomputedFingerprint()).isNotEqualTo(second.getPrecomputedFingerprint());
assertThat(first).isNotEqualTo(second);