Skip to content

Instantly share code, notes, and snippets.

@lptr
Created October 27, 2023 20:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lptr/e21f611bce2ed361783ea96fd779ef99 to your computer and use it in GitHub Desktop.
Save lptr/e21f611bce2ed361783ea96fd779ef99 to your computer and use it in GitHub Desktop.
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/AbstractCrossProcessCacheAccess.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/AbstractCrossProcessCacheAccess.java
index 592be29565d..567eefc1359 100644
--- a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/AbstractCrossProcessCacheAccess.java
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/AbstractCrossProcessCacheAccess.java
@@ -16,19 +16,58 @@
package org.gradle.cache.internal;
-import org.gradle.cache.CrossProcessCacheAccess;
+import org.gradle.api.Action;
+import org.gradle.cache.FileLock;
+import org.gradle.cache.FileLockManager;
+import org.gradle.cache.FileLockReleasedSignal;
+import org.gradle.cache.LockOptions;
+import org.gradle.internal.UncheckedException;
-import java.io.Closeable;
+import java.io.File;
-public abstract class AbstractCrossProcessCacheAccess implements CrossProcessCacheAccess, Closeable {
- /**
- * Opens this cache access instance when the cache is opened. State lock is held while this method is called.
- */
- public abstract void open();
+public abstract class AbstractCrossProcessCacheAccess implements CrossProcessCacheAccessInternal {
+ protected final String cacheDisplayName;
+ protected final File lockTarget;
+ protected final LockOptions lockOptions;
+ protected final FileLockManager lockManager;
- /**
- * Closes this cache access instance when the cache is opened. State lock is held while this method is called.
- */
- @Override
- public abstract void close();
+ protected final CacheInitializationAction initializationAction;
+ protected final Action<FileLock> onOpenAction;
+ protected final Action<FileLock> onCloseAction;
+ protected FileLock fileLock;
+
+ public AbstractCrossProcessCacheAccess(
+ String cacheDisplayName,
+ File lockTarget,
+ LockOptions lockOptions,
+ FileLockManager lockManager,
+ CacheInitializationAction initializationAction,
+ Action<FileLock> onOpenAction,
+ Action<FileLock> onCloseAction
+ ) {
+ this.cacheDisplayName = cacheDisplayName;
+ this.lockTarget = lockTarget;
+ this.lockOptions = lockOptions;
+ this.lockManager = lockManager;
+ this.initializationAction = initializationAction;
+ this.onOpenAction = onOpenAction;
+ this.onCloseAction = onCloseAction;
+ }
+
+ protected FileLock getFileLock(
+ Action<FileLockReleasedSignal> whenContended
+ ) {
+ final FileLock fileLock = lockManager.lock(lockTarget, lockOptions, cacheDisplayName, "", whenContended);
+ try {
+ boolean rebuild = initializationAction.requiresInitialization(fileLock);
+ if (rebuild) {
+ fileLock.writeFile(() -> initializationAction.initialize(fileLock));
+ }
+ onOpenAction.execute(fileLock);
+ return fileLock;
+ } catch (Exception e) {
+ fileLock.close();
+ throw UncheckedException.throwAsUncheckedException(e);
+ }
+ }
}
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/CrossProcessCacheAccessInternal.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/CrossProcessCacheAccessInternal.java
new file mode 100644
index 00000000000..ba2d1e38752
--- /dev/null
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/CrossProcessCacheAccessInternal.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 the original author or authors.
+ *
+ * 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 org.gradle.cache.internal;
+
+import org.gradle.cache.CrossProcessCacheAccess;
+
+import java.io.Closeable;
+
+public interface CrossProcessCacheAccessInternal extends CrossProcessCacheAccess, Closeable {
+ /**
+ * Opens this cache access instance when the cache is opened. State lock is held while this method is called.
+ */
+ void open();
+
+ /**
+ * Closes this cache access instance when the cache is opened. State lock is held while this method is called.
+ */
+ @Override
+ void close();
+}
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/DefaultCacheCoordinator.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/DefaultCacheCoordinator.java
index bf50750506b..1fa098fa4c4 100644
--- a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/DefaultCacheCoordinator.java
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/DefaultCacheCoordinator.java
@@ -72,7 +72,7 @@ public class DefaultCacheCoordinator implements CacheCreationCoordinator, Exclus
private final ExecutorFactory executorFactory;
private final FileAccess fileAccess;
private final Map<String, IndexedCacheEntry<?, ?>> caches = new HashMap<String, IndexedCacheEntry<?, ?>>();
- private final AbstractCrossProcessCacheAccess crossProcessCacheAccess;
+ private final CrossProcessCacheAccessInternal crossProcessCacheAccess;
private final CacheAccessOperationsStack operations;
private ManagedExecutor cacheUpdateExecutor;
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedExclusiveModeCrossProcessCacheAccess.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedExclusiveModeCrossProcessCacheAccess.java
index eb73c5e2d4c..faa3b64b6c7 100644
--- a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedExclusiveModeCrossProcessCacheAccess.java
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedExclusiveModeCrossProcessCacheAccess.java
@@ -25,7 +25,6 @@
import org.gradle.cache.LockOptions;
import org.gradle.internal.Actions;
import org.gradle.internal.Factory;
-import org.gradle.internal.UncheckedException;
import java.io.File;
@@ -37,25 +36,9 @@
public class FixedExclusiveModeCrossProcessCacheAccess extends AbstractCrossProcessCacheAccess {
private final static Action<FileLockReleasedSignal> NO_OP_CONTENDED_ACTION = Actions.doNothing();
- private final String cacheDisplayName;
- private final File lockTarget;
- private final LockOptions lockOptions;
- private final FileLockManager lockManager;
- private final CacheInitializationAction initializationAction;
- private final Action<FileLock> onOpenAction;
- private final Action<FileLock> onCloseAction;
- private FileLock fileLock;
-
public FixedExclusiveModeCrossProcessCacheAccess(String cacheDisplayName, File lockTarget, LockOptions lockOptions, FileLockManager lockManager, CacheInitializationAction initializationAction, Action<FileLock> onOpenAction, Action<FileLock> onCloseAction) {
+ super(cacheDisplayName, lockTarget, lockOptions, lockManager, initializationAction, onOpenAction, onCloseAction);
assert lockOptions.getMode() == Exclusive;
- this.initializationAction = initializationAction;
- this.onOpenAction = onOpenAction;
- this.onCloseAction = onCloseAction;
- assert lockOptions.getMode() == Exclusive;
- this.cacheDisplayName = cacheDisplayName;
- this.lockTarget = lockTarget;
- this.lockOptions = lockOptions;
- this.lockManager = lockManager;
}
@Override
@@ -63,30 +46,7 @@ public void open() {
if (fileLock != null) {
throw new IllegalStateException("File lock " + lockTarget + " is already open.");
}
- this.fileLock = getFileLock(lockManager, lockTarget, lockOptions, cacheDisplayName, initializationAction, onOpenAction, NO_OP_CONTENDED_ACTION);
- }
-
- static FileLock getFileLock(
- FileLockManager lockManager,
- File lockTarget,
- LockOptions lockOptions,
- String cacheDisplayName,
- CacheInitializationAction initializationAction,
- Action<FileLock> onOpenAction,
- Action<FileLockReleasedSignal> whenContended
- ) {
- final FileLock fileLock = lockManager.lock(lockTarget, lockOptions, cacheDisplayName, "", whenContended);
- try {
- boolean rebuild = initializationAction.requiresInitialization(fileLock);
- if (rebuild) {
- fileLock.writeFile(() -> initializationAction.initialize(fileLock));
- }
- onOpenAction.execute(fileLock);
- return fileLock;
- } catch (Exception e) {
- fileLock.close();
- throw UncheckedException.throwAsUncheckedException(e);
- }
+ this.fileLock = getFileLock(NO_OP_CONTENDED_ACTION);
}
@Override
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedSharedModeCrossProcessCacheAccess.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedSharedModeCrossProcessCacheAccess.java
index bfc6864f64a..f41a5465a17 100644
--- a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedSharedModeCrossProcessCacheAccess.java
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/FixedSharedModeCrossProcessCacheAccess.java
@@ -35,24 +35,10 @@
* exclusive lock be held, so this implementation simply throws 'not supported' exceptions for these methods.
*/
public class FixedSharedModeCrossProcessCacheAccess extends AbstractCrossProcessCacheAccess {
- private final String cacheDisplayName;
- private final File lockTarget;
- private final LockOptions lockOptions;
- private final FileLockManager lockManager;
- private final CacheInitializationAction initializationAction;
- private final Action<FileLock> onOpenAction;
- private final Action<FileLock> onCloseAction;
- private FileLock fileLock;
public FixedSharedModeCrossProcessCacheAccess(String cacheDisplayName, File lockTarget, LockOptions lockOptions, FileLockManager lockManager, CacheInitializationAction initializationAction, Action<FileLock> onOpenAction, Action<FileLock> onCloseAction) {
+ super(cacheDisplayName, lockTarget, lockOptions, lockManager, initializationAction, onOpenAction, onCloseAction);
assert lockOptions.getMode() == Shared;
- this.cacheDisplayName = cacheDisplayName;
- this.lockTarget = lockTarget;
- this.lockOptions = lockOptions;
- this.lockManager = lockManager;
- this.initializationAction = initializationAction;
- this.onOpenAction = onOpenAction;
- this.onCloseAction = onCloseAction;
}
@Override
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/LockOnDemandCrossProcessCacheAccess.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/LockOnDemandCrossProcessCacheAccess.java
index fa43e64931d..661da8e7406 100644
--- a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/LockOnDemandCrossProcessCacheAccess.java
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/LockOnDemandCrossProcessCacheAccess.java
@@ -33,39 +33,26 @@
public class LockOnDemandCrossProcessCacheAccess extends AbstractCrossProcessCacheAccess {
private static final Logger LOGGER = LoggerFactory.getLogger(LockOnDemandCrossProcessCacheAccess.class);
- private final String cacheDisplayName;
- private final File lockTarget;
- private final LockOptions lockOptions;
- private final FileLockManager lockManager;
+
private final Lock stateLock;
- private final Action<FileLock> onOpen;
- private final Action<FileLock> onClose;
private final Runnable unlocker;
private final Action<FileLockReleasedSignal> whenContended;
private int lockCount;
- private FileLock fileLock;
- private CacheInitializationAction initAction;
private FileLockReleasedSignal lockReleaseSignal;
/**
* Actions are notified when lock is opened or closed. Actions are called while holding state lock, so that no other threads are working with cache while these are running.
*
* @param stateLock Lock to hold while mutating state.
- * @param onOpen Action to run when the lock is opened. Action is called while holding state lock
- * @param onClose Action to run when the lock is closed. Action is called while holding state lock
+ * @param onOpenAction Action to run when the lock is opened. Action is called while holding state lock
+ * @param onCloseAction Action to run when the lock is closed. Action is called while holding state lock
*/
- public LockOnDemandCrossProcessCacheAccess(String cacheDisplayName, File lockTarget, LockOptions lockOptions, FileLockManager lockManager, Lock stateLock, CacheInitializationAction initAction, Action<FileLock> onOpen, Action<FileLock> onClose) {
+ public LockOnDemandCrossProcessCacheAccess(String cacheDisplayName, File lockTarget, LockOptions lockOptions, FileLockManager lockManager, Lock stateLock, CacheInitializationAction initializationAction, Action<FileLock> onOpenAction, Action<FileLock> onCloseAction) {
+ super(cacheDisplayName, lockTarget, lockOptions, lockManager, initializationAction, onOpenAction, onCloseAction);
checkArgument(lockOptions.getMode() == Exclusive, "Only supported lock mode is exclusive.");
- this.cacheDisplayName = cacheDisplayName;
- this.lockTarget = lockTarget;
- this.lockOptions = lockOptions;
- this.lockManager = lockManager;
this.stateLock = stateLock;
- this.initAction = initAction;
- this.onOpen = onOpen;
- this.onClose = onClose;
- unlocker = new UnlockAction();
- whenContended = new ContendedAction();
+ this.unlocker = new UnlockAction();
+ this.whenContended = new ContendedAction();
}
@Override
@@ -106,7 +93,7 @@ private void incrementLockCount() {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Acquiring file lock for {}", cacheDisplayName);
}
- fileLock = getFileLock(lockOptions);
+ fileLock = getFileLock(whenContended);
}
lockCount++;
} finally {
@@ -114,10 +101,6 @@ private void incrementLockCount() {
}
}
- private FileLock getFileLock(LockOptions lockOptions) {
- return FixedExclusiveModeCrossProcessCacheAccess.getFileLock(lockManager, lockTarget, lockOptions, cacheDisplayName, initAction, onOpen, whenContended);
- }
-
private void decrementLockCount() {
stateLock.lock();
try {
@@ -141,7 +124,7 @@ private void releaseLockIfHeld() {
LOGGER.debug("Releasing file lock for {}", cacheDisplayName);
}
try {
- onClose.execute(fileLock);
+ onCloseAction.execute(fileLock);
} finally {
try {
fileLock.close();
diff --git a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/NoLockingCacheAccess.java b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/NoLockingCacheAccess.java
index 4c13372d4dc..8bb327e4488 100644
--- a/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/NoLockingCacheAccess.java
+++ b/platforms/core-execution/persistent-cache/src/main/java/org/gradle/cache/internal/NoLockingCacheAccess.java
@@ -18,7 +18,7 @@
import org.gradle.internal.Factory;
-class NoLockingCacheAccess extends AbstractCrossProcessCacheAccess {
+class NoLockingCacheAccess implements CrossProcessCacheAccessInternal {
private final Runnable onClose;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment