Skip to content

Commit

Permalink
Merge pull request #133 from jenkinsci/feature/132-make-maxcachesize-…
Browse files Browse the repository at this point in the history
…optional

Make maxCacheSize optional
  • Loading branch information
repolevedavaj authored Jan 3, 2023
2 parents eefa641 + 658032c commit c42ad64
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 48 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ The storage type can be configured in the global configuration section of Jenkin

The following cache configuration options apply to all supported job types.

| Option | Mandatory | Description |
|-----------------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `maxCacheSize` | yes | The maximum size in megabytes of all configured caches that Jenkins will allow until it deletes all completely and starts the next build from an empty cache. This prevents caches from growing indefinitely with the downside of periodic fresh builds without a cache. |
| `defaultBranch` | no | If the current branch has no cache, it will seed its cache from the specified branch. Leave empty to generate a fresh cache for each branch. |
| `caches` | yes | Defines the caches to use in the job (see below). |
| Option | Mandatory | Description |
|-----------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `maxCacheSize` | no | The maximum size in megabytes of all configured caches that Jenkins will allow until it deletes all completely and starts the next build from an empty cache. This prevents caches from growing indefinitely with the downside of periodic fresh builds without a cache. Set to zero or empty to skip checking cache size. |
| `defaultBranch` | no | If the current branch has no cache, it will seed its cache from the specified branch. Leave empty to generate a fresh cache for each branch. |
| `caches` | yes | Defines the caches to use in the job (see below). |

### `ArbitraryFileCache`

Expand Down
23 changes: 17 additions & 6 deletions src/main/java/jenkins/plugins/jobcacher/CacheManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,16 @@ public static List<Cache.Saver> cache(ItemStorage<?> storage, Run<?, ?> run, Fil
/**
* Internal method only
*/
public static void save(ItemStorage<?> storage, Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener, long maxCacheSize, List<Cache> caches, List<Cache.Saver> cacheSavers) throws IOException, InterruptedException {
public static void save(ItemStorage<?> storage, Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener, Long maxCacheSize, List<Cache> caches, List<Cache.Saver> cacheSavers) throws IOException, InterruptedException {
ObjectPath cachePath = getCachePath(storage, run);

// First calculate size of cache to check if it should just be deleted
long totalSize = 0L;
for (Cache.Saver saver : cacheSavers) {
totalSize += saver.calculateSize(cachePath, run, workspace, launcher, listener);
}
boolean exceedsMaxCacheSize = exceedsMaxCacheSize(cachePath, run, workspace, launcher, listener, maxCacheSize, cacheSavers);

// synchronize on the build's parent object as we are going to write to the shared cache
synchronized (getLock(run.getParent())) {
// If total size is greater than configured maximum, delete all caches to start fresh next build
if (totalSize > maxCacheSize * 1024 * 1024) {
if (exceedsMaxCacheSize) {
listener.getLogger().println("Removing job cache as it has grown beyond configured maximum size of " +
maxCacheSize + "M. Next build will start with no cache.");

Expand All @@ -108,4 +105,18 @@ public static void save(ItemStorage<?> storage, Run<?, ?> run, FilePath workspac
run.getAction(CacheBuildLastAction.class).addCaches(caches);
}
}

private static boolean exceedsMaxCacheSize(ObjectPath cachePath, Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener, Long maxCacheSize, List<Cache.Saver> cacheSavers) throws IOException, InterruptedException {
if (maxCacheSize == null || maxCacheSize == 0) {
return false;
}

long totalSize = 0L;
for (Cache.Saver saver : cacheSavers) {
totalSize += saver.calculateSize(cachePath, run, workspace, launcher, listener);
}

return totalSize > maxCacheSize * 1024 * 1024;
}

}
14 changes: 7 additions & 7 deletions src/main/java/jenkins/plugins/jobcacher/CacheWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,15 @@
*/
public class CacheWrapper extends SimpleBuildWrapper {

private long maxCacheSize;
private Long maxCacheSize;
private List<Cache> caches;
private String defaultBranch;

public CacheWrapper() {
}

@DataBoundConstructor
public CacheWrapper(long maxCacheSize, List<Cache> caches) {
setMaxCacheSize(maxCacheSize);
public CacheWrapper(List<Cache> caches) {
setCaches(caches);
}

Expand All @@ -73,12 +72,13 @@ public ItemStorage<?> getStorage() {
}

@SuppressWarnings("unused")
public long getMaxCacheSize() {
public Long getMaxCacheSize() {
return maxCacheSize;
}

@DataBoundSetter
@SuppressWarnings("unused")
public void setMaxCacheSize(long maxCacheSize) {
public void setMaxCacheSize(Long maxCacheSize) {
this.maxCacheSize = maxCacheSize;
}

Expand Down Expand Up @@ -141,12 +141,12 @@ private static class CacheDisposer extends Disposer {
private static final long serialVersionUID = 1L;

private final ItemStorage<?> storage;
private final long maxCacheSize;
private final Long maxCacheSize;
private final List<Cache> caches;
private final List<Cache.Saver> cacheSavers;

@DataBoundConstructor
public CacheDisposer(ItemStorage<?> storage, long maxCacheSize, List<Cache> caches, List<Cache.Saver> cacheSavers) {
public CacheDisposer(ItemStorage<?> storage, Long maxCacheSize, List<Cache> caches, List<Cache.Saver> cacheSavers) {
this.storage = storage;
this.maxCacheSize = maxCacheSize;
this.caches = caches;
Expand Down
43 changes: 28 additions & 15 deletions src/main/java/jenkins/plugins/jobcacher/pipeline/CacheStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,39 +42,52 @@
import org.kohsuke.stapler.DataBoundSetter;

import java.io.IOException;
import java.util.*;
import java.util.Collections;
import java.util.List;

/**
* Wrapping workflow step that automatically seeds the specified path with the previous run and on exit of the
* block, saves that cache to the configured item storage.
*/
public class CacheStep extends Step {

private final long maxCacheSize;
private final List<Cache> caches;
@DataBoundSetter
public String defaultBranch = null;
private Long maxCacheSize;

public String defaultBranch;

@DataBoundConstructor
public CacheStep(long maxCacheSize, List<Cache> caches) {
public CacheStep(Long maxCacheSize, List<Cache> caches) {
this.maxCacheSize = maxCacheSize;
this.caches = caches;
}

@DataBoundSetter
@SuppressWarnings("unused")
public long getMaxCacheSize() {
return maxCacheSize;
}

public List<Cache> getCaches() {
return caches;
public void setDefaultBranch(String defaultBranch) {
this.defaultBranch = defaultBranch;
}

@SuppressWarnings("unused")
public String getDefaultBranch() {
return defaultBranch;
}

@DataBoundSetter
@SuppressWarnings("unused")
public void setMaxCacheSize(Long maxCacheSize) {
this.maxCacheSize = maxCacheSize;
}

@SuppressWarnings("unused")
public Long getMaxCacheSize() {
return maxCacheSize;
}

public List<Cache> getCaches() {
return caches;
}

@Override
public StepExecution start(StepContext context) throws Exception {
return new ExecutionImpl(context, maxCacheSize, caches, defaultBranch);
Expand All @@ -84,11 +97,11 @@ public static class ExecutionImpl extends GeneralNonBlockingStepExecution {

private static final long serialVersionUID = 1L;

private final long maxCacheSize;
private final Long maxCacheSize;
private final List<Cache> caches;
private final String defaultBranch;

protected ExecutionImpl(StepContext context, long maxCacheSize, List<Cache> caches, String defaultBranch) {
protected ExecutionImpl(StepContext context, Long maxCacheSize, List<Cache> caches, String defaultBranch) {
super(context);

this.maxCacheSize = maxCacheSize;
Expand Down Expand Up @@ -125,11 +138,11 @@ public static class ExecutionCallback extends BodyExecutionCallback {

private static final long serialVersionUID = 1L;

private final long maxCacheSize;
private final Long maxCacheSize;
private final List<Cache> caches;
private final List<Cache.Saver> cacheSavers;

public ExecutionCallback(long maxCacheSize, List<Cache> caches, List<Cache.Saver> cacheSavers) {
public ExecutionCallback(Long maxCacheSize, List<Cache> caches, List<Cache.Saver> cacheSavers) {
this.maxCacheSize = maxCacheSize;
this.caches = caches;
this.cacheSavers = cacheSavers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
</f:entry>

<f:entry title="${%Compression method}" field="compressionMethod">
<f:select default="NONE"/>
<f:select default="TARGZ"/>
</f:entry>
</f:advanced>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,22 @@
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="${%Maximum Cache Size}" field="maxCacheSize" help="/plugin/jobcacher/help-maximumCacheSize.html">
<f:textbox/>
</f:entry>

<f:entry title="${%Caches}">
<f:hetero-list name="caches" descriptors="${descriptor.cacheDescriptors}" items="${instance.caches}"
addCaption="${%Add Cache}" hasHeader="true"
targetType="jenkins.plugins.jobcacher.Cache.class"/>
</f:entry>

<f:entry title="${%Branch to use for default cache}" field="defaultBranch" help="/plugin/jobcacher/help-defaultBranch.html">
<f:textbox/>
</f:entry>
<f:advanced>
<f:entry title="${%Maximum Cache Size}" field="maxCacheSize"
help="/plugin/jobcacher/help-maximumCacheSize.html">
<f:textbox/>
</f:entry>
<f:entry title="${%Branch to use for default cache}" field="defaultBranch"
help="/plugin/jobcacher/help-defaultBranch.html">
<f:textbox/>
</f:entry>
</f:advanced>

</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,22 @@
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="${%Maximum Cache Size}" field="maxCacheSize" help="/plugin/jobcacher/help-maximumCacheSize.html">
<f:textbox/>
</f:entry>

<f:entry title="${%Caches}">
<f:hetero-list name="caches" descriptors="${descriptor.cacheDescriptors}" items="${instance.caches}"
addCaption="${%Add Cache}" hasHeader="true"
targetType="jenkins.plugins.jobcacher.Cache.class"/>
</f:entry>

<f:entry title="${%Branch to use for default cache}" field="defaultBranch" help="/plugin/jobcacher/help-defaultBranch.html">
<f:textbox/>
</f:entry>
<f:advanced>
<f:entry title="${%Maximum Cache Size}" field="maxCacheSize"
help="/plugin/jobcacher/help-maximumCacheSize.html">
<f:textbox/>
</f:entry>
<f:entry title="${%Branch to use for default cache}" field="defaultBranch"
help="/plugin/jobcacher/help-defaultBranch.html">
<f:textbox/>
</f:entry>
</f:advanced>

</j:jelly>
2 changes: 1 addition & 1 deletion src/main/webapp/help-maximumCacheSize.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
<div>
The maximum size in megabytes of all configured caches that Jenkins will allow until it deletes all completely and
starts the next build from an empty cache. This prevents caches from growing indefinitely with the downside of
periodic fresh builds without a cache.
periodic fresh builds without a cache. Set to zero or empty to skip checking cache size.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ private FreeStyleProject createProjectWithFullyConfiguredArbitraryFileCache(Stri
cache.setUseDefaultExcludes(false);
cache.setCacheName("cacheName");

CacheWrapper cacheWrapper = new CacheWrapper(999, Collections.singletonList(cache));
CacheWrapper cacheWrapper = new CacheWrapper(Collections.singletonList(cache));
cacheWrapper.setMaxCacheSize(999L);
cacheWrapper.setDefaultBranch("develop");

FreeStyleProject project = jenkins.createProject(FreeStyleProject.class, name);
Expand Down

0 comments on commit c42ad64

Please sign in to comment.