Skip to content

Commit 197b051

Browse files
committed
force cache delete option
add the possibility to force delete the cache dir ignoring any possible problems this can cause.
1 parent fd4c0e7 commit 197b051

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryCachingConfiguration.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@
1717
import java.util.List;
1818
import java.util.concurrent.TimeUnit;
1919
import java.util.concurrent.locks.ReentrantReadWriteLock;
20+
import java.util.logging.Level;
21+
import java.util.logging.Logger;
22+
2023
import org.apache.commons.io.IOUtils;
2124
import org.apache.commons.lang.StringUtils;
2225

2326
public final class LibraryCachingConfiguration extends AbstractDescribableImpl<LibraryCachingConfiguration> {
27+
28+
private static final Logger LOGGER = Logger.getLogger(LibraryCachingConfiguration.class.getName());
29+
2430
private int refreshTimeMinutes;
2531
private String excludedVersionsStr;
2632

@@ -83,7 +89,7 @@ public static FilePath getGlobalLibrariesCacheDir() {
8389
}
8490

8591
@Extension public static class DescriptorImpl extends Descriptor<LibraryCachingConfiguration> {
86-
public FormValidation doClearCache(@QueryParameter String name) throws InterruptedException {
92+
public FormValidation doClearCache(@QueryParameter String name, @QueryParameter boolean forceDelete) throws InterruptedException {
8793
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
8894

8995
try {
@@ -94,19 +100,26 @@ public FormValidation doClearCache(@QueryParameter String name) throws Interrupt
94100
try (InputStream stream = libraryNamePath.read()) {
95101
cacheName = IOUtils.toString(stream, StandardCharsets.UTF_8);
96102
}
97-
if (libraryNamePath.readToString().equals(name)) {
103+
if (cacheName.equals(name)) {
98104
FilePath libraryCachePath = LibraryCachingConfiguration.getGlobalLibrariesCacheDir()
99105
.child(libraryNamePath.getName().replace("-name.txt", ""));
100-
ReentrantReadWriteLock retrieveLock = LibraryAdder.getReadWriteLockFor(libraryCachePath.getName());
101-
if (retrieveLock.writeLock().tryLock(10, TimeUnit.SECONDS)) {
102-
try {
103-
libraryCachePath.deleteRecursive();
104-
libraryNamePath.delete();
105-
} finally {
106-
retrieveLock.writeLock().unlock();
107-
}
106+
if (forceDelete) {
107+
LOGGER.log(Level.FINER, "Force deleting cache for {0}", name);
108+
libraryCachePath.deleteRecursive();
109+
libraryNamePath.delete();
108110
} else {
109-
return FormValidation.error("The cache dir is currently used by another thread, so deletion was not possibly. Please try again");
111+
LOGGER.log(Level.FINER, "Safe deleting cache for {0}", name);
112+
ReentrantReadWriteLock retrieveLock = LibraryAdder.getReadWriteLockFor(libraryCachePath.getName());
113+
if (retrieveLock.writeLock().tryLock(10, TimeUnit.SECONDS)) {
114+
try {
115+
libraryCachePath.deleteRecursive();
116+
libraryNamePath.delete();
117+
} finally {
118+
retrieveLock.writeLock().unlock();
119+
}
120+
} else {
121+
return FormValidation.error("The cache dir could not be deleted because it is currently being used by another thread. Please try again.");
122+
}
110123
}
111124
}
112125
}

src/main/resources/org/jenkinsci/plugins/workflow/libs/LibraryCachingConfiguration/config.jelly

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ THE SOFTWARE.
3232
<f:textbox />
3333
</f:entry>
3434
<j:if test="${h.hasPermission(app.ADMINISTER)}">
35-
<f:validateButton title="${%Clear cache}" progress="${%Clearing...}" method="clearCache" with="name" />
35+
<f:entry title="${%Force clear cache}" field="forceDelete">
36+
<f:checkbox/>
37+
</f:entry>
38+
<f:validateButton title="${%Clear cache}" progress="${%Clearing...}" method="clearCache" with="name,forceDelete" />
3639
</j:if>
3740
</j:jelly>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<div>
2+
To avoid that clearing the cache interferes with running builds this process is normally guarded by locks.
3+
Pressing the <i>Clear Cache</i> button will wait for a maximum of 10 seconds to get a lock.<br/>
4+
By checking this option, the library will be deleted immediately without acquiring a lock. This can lead to build errors
5+
if a build is copying the library from the cache while it gets delete. This risk is all the greater, the larger the library is.
6+
</div>

src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryCachingConfigurationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public void clearCache() throws Exception {
177177
assertThat(new File(cache.getRemote()), anExistingDirectory());
178178
assertThat(new File(cache.withSuffix("-name.txt").getRemote()), anExistingFile());
179179
// Clear the cache. TODO: Would be more realistic to set up security and use WebClient.
180-
ExtensionList.lookupSingleton(LibraryCachingConfiguration.DescriptorImpl.class).doClearCache("library");
180+
ExtensionList.lookupSingleton(LibraryCachingConfiguration.DescriptorImpl.class).doClearCache("library", false);
181181
assertThat(new File(cache.getRemote()), not(anExistingDirectory()));
182182
assertThat(new File(cache.withSuffix("-name.txt").getRemote()), not(anExistingFile()));
183183
}

0 commit comments

Comments
 (0)