Skip to content

Instantly share code, notes, and snippets.

@lptr
Created April 24, 2025 14:56
Show Gist options
  • Select an option

  • Save lptr/8108ad72aaa9666a73bdca0bd6e93032 to your computer and use it in GitHub Desktop.

Select an option

Save lptr/8108ad72aaa9666a73bdca0bd6e93032 to your computer and use it in GitHub Desktop.
diff --git i/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/ImmutableWorkspaceMetadataStore.java w/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/ImmutableWorkspaceMetadataStore.java
index 58fe88c4f8b..17d41379ca2 100644
--- i/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/ImmutableWorkspaceMetadataStore.java
+++ w/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/ImmutableWorkspaceMetadataStore.java
@@ -20,11 +20,12 @@
import org.gradle.internal.service.scopes.ServiceScope;
import java.io.File;
+import java.util.Optional;
@ServiceScope(Scope.Global.class)
public interface ImmutableWorkspaceMetadataStore {
- ImmutableWorkspaceMetadata loadWorkspaceMetadata(File workspace);
+ Optional<ImmutableWorkspaceMetadata> loadWorkspaceMetadata(File workspace);
void storeWorkspaceMetadata(File workspace, ImmutableWorkspaceMetadata metadata);
diff --git i/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/impl/DefaultImmutableWorkspaceMetadataStore.java w/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/impl/DefaultImmutableWorkspaceMetadataStore.java
index 28b174c3392..bdc3ae22748 100644
--- i/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/impl/DefaultImmutableWorkspaceMetadataStore.java
+++ w/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/history/impl/DefaultImmutableWorkspaceMetadataStore.java
@@ -24,24 +24,28 @@
import org.gradle.internal.serialize.HashCodeSerializer;
import org.gradle.internal.serialize.kryo.KryoBackedDecoder;
import org.gradle.internal.serialize.kryo.KryoBackedEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.Map;
+import java.util.Optional;
public class DefaultImmutableWorkspaceMetadataStore implements ImmutableWorkspaceMetadataStore {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultImmutableWorkspaceMetadataStore.class);
private static final String METADATA_FILE = "metadata.bin";
private final HashCodeSerializer hashCodeSerializer = new HashCodeSerializer();
private final OriginMetadataSerializer originMetadataSerializer = new OriginMetadataSerializer();
@Override
- public ImmutableWorkspaceMetadata loadWorkspaceMetadata(File workspace) {
+ public Optional<ImmutableWorkspaceMetadata> loadWorkspaceMetadata(File workspace) {
File metadataFile = new File(workspace, METADATA_FILE);
- //noinspection IOStreamConstructor
try (KryoBackedDecoder decoder = new KryoBackedDecoder(new FileInputStream(metadataFile))) {
OriginMetadata originMetadata = originMetadataSerializer.read(decoder);
@@ -55,7 +59,10 @@ public ImmutableWorkspaceMetadata loadWorkspaceMetadata(File workspace) {
outputPropertyHashes.put(outputProperty, hashCode);
}
}
- return new ImmutableWorkspaceMetadata(originMetadata, outputPropertyHashes.build());
+ return Optional.of(new ImmutableWorkspaceMetadata(originMetadata, outputPropertyHashes.build()));
+ } catch (FileNotFoundException e) {
+ LOGGER.debug("Workspace metadata file not found: " + metadataFile, e);
+ return Optional.empty();
} catch (IOException e) {
throw new UncheckedIOException("Could not read workspace metadata from " + metadataFile, e);
}
diff --git i/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/steps/AssignImmutableWorkspaceStep.java w/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/steps/AssignImmutableWorkspaceStep.java
index fba1bffe6dd..7a794e93c57 100644
--- i/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/steps/AssignImmutableWorkspaceStep.java
+++ w/platforms/core-execution/execution/src/main/java/org/gradle/internal/execution/steps/AssignImmutableWorkspaceStep.java
@@ -126,7 +126,15 @@ private Optional<WorkspaceResult> loadImmutableWorkspaceIfExists(UnitOfWork work
FileSystemLocationSnapshot workspaceSnapshot = fileSystemAccess.read(immutableLocation.getAbsolutePath());
switch (workspaceSnapshot.getType()) {
case Directory:
- return loadImmutableWorkspaceIfConsistent(work, workspace);
+ Optional<WorkspaceResult> result = loadImmutableWorkspaceIfConsistent(work, workspace);
+ if (!result.isPresent()) {
+ // Invalidate VFS, and log that we are going to recreate the workspace
+ // (this is a bit of a hack, but we need to invalidate the VFS for the workspace location
+ // so that the next read will not return the old content)
+ fileSystemAccess.invalidate(ImmutableList.of(immutableLocation.getAbsolutePath()));
+ LOGGER.debug("Immutable workspace is inconsistent, will be recreated: {}", immutableLocation.getAbsolutePath());
+ }
+ return result;
case RegularFile:
throw new IllegalStateException(
"Immutable workspace is occupied by a file: " + immutableLocation.getAbsolutePath() + ". " +
@@ -144,15 +152,16 @@ private Optional<WorkspaceResult> loadImmutableWorkspaceIfConsistent(UnitOfWork
// Verify output hashes
ImmutableListMultimap<String, HashCode> outputHashes = calculateOutputHashes(outputSnapshots);
- ImmutableWorkspaceMetadata metadata = workspaceMetadataStore.loadWorkspaceMetadata(immutableLocation);
- if (!metadata.getOutputPropertyHashes().equals(outputHashes)) {
- return workspace.withTemporaryWorkspace(temporaryWorkspace -> {
- moveInconsistentImmutableWorkspaceToTemporaryLocation(immutableLocation, temporaryWorkspace, outputSnapshots);
- return Optional.empty();
- });
- }
+ return workspaceMetadataStore.loadWorkspaceMetadata(immutableLocation).map(metadata -> {
+ if (!metadata.getOutputPropertyHashes().equals(outputHashes)) {
+ return workspace.withTemporaryWorkspace(temporaryWorkspace -> {
+ moveInconsistentImmutableWorkspaceToTemporaryLocation(immutableLocation, temporaryWorkspace, outputSnapshots);
+ return null;
+ });
+ }
- return Optional.of(loadImmutableWorkspace(work, immutableLocation, metadata, outputSnapshots));
+ return loadImmutableWorkspace(work, immutableLocation, metadata, outputSnapshots);
+ });
}
private static WorkspaceResult loadImmutableWorkspace(UnitOfWork work, File immutableLocation, ImmutableWorkspaceMetadata metadata, ImmutableSortedMap<String, FileSystemSnapshot> outputSnapshots) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment