diff --git a/source/java/org/alfresco/repo/content/caching/cleanup/CachedContentCleaner.java b/source/java/org/alfresco/repo/content/caching/cleanup/CachedContentCleaner.java
index f1bd735161..44278bc88e 100644
--- a/source/java/org/alfresco/repo/content/caching/cleanup/CachedContentCleaner.java
+++ b/source/java/org/alfresco/repo/content/caching/cleanup/CachedContentCleaner.java
@@ -20,7 +20,6 @@ package org.alfresco.repo.content.caching.cleanup;
import java.io.File;
import java.util.Date;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.repo.content.caching.CacheFileProps;
import org.alfresco.repo.content.caching.ContentCacheImpl;
@@ -46,7 +45,6 @@ public class CachedContentCleaner extends Thread implements FileHandler, Applica
private ContentCacheImpl cache; // impl specific functionality required
private long minFileAgeMillis = 0;
private Integer maxDeleteWatchCount = 1;
- private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private boolean running;
private UsageTracker usageTracker;
private long newDiskUsage;
@@ -58,7 +56,6 @@ public class CachedContentCleaner extends Thread implements FileHandler, Applica
private Date timeFinished;
private ApplicationEventPublisher eventPublisher;
private long targetReductionBytes;
- private boolean cleanRequested;
private String reasonMessage;
@@ -99,9 +96,9 @@ public class CachedContentCleaner extends Thread implements FileHandler, Applica
execute(reason);
}
- private synchronized void doClean()
- {
- while (running || (!cleanRequested))
+ private void doClean()
+ {
+ synchronized(this)
{
try
{
@@ -112,7 +109,6 @@ public class CachedContentCleaner extends Thread implements FileHandler, Applica
// Nothing to do.
}
}
-
running = true;
if (log.isInfoEnabled())
{
@@ -138,18 +134,19 @@ public class CachedContentCleaner extends Thread implements FileHandler, Applica
", target: " + targetReductionBytes + " bytes");
}
- cleanRequested = false;
this.targetReductionBytes = 0;
running = false;
- notifyAll();
+ synchronized(this)
+ {
+ notifyAll();
+ }
}
public synchronized void execute(String reasonMessage)
{
this.reasonMessage = reasonMessage;
- cleanRequested = true;
notifyAll();
}
@@ -386,15 +383,7 @@ public class CachedContentCleaner extends Thread implements FileHandler, Applica
public boolean isRunning()
{
- lock.readLock().lock();
- try
- {
- return running;
- }
- finally
- {
- lock.readLock().unlock();
- }
+ return running;
}
public long getNumFilesSeen()
diff --git a/source/java/org/alfresco/repo/content/caching/quota/StandardQuotaStrategyTest.java b/source/java/org/alfresco/repo/content/caching/quota/StandardQuotaStrategyTest.java
index ab1df2a376..78e0384777 100644
--- a/source/java/org/alfresco/repo/content/caching/quota/StandardQuotaStrategyTest.java
+++ b/source/java/org/alfresco/repo/content/caching/quota/StandardQuotaStrategyTest.java
@@ -29,7 +29,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import org.alfresco.repo.content.ContentContext;
@@ -48,7 +47,6 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.mozilla.javascript.ObjToIntMap.Iterator;
import org.springframework.context.ApplicationContext;
/**
@@ -191,4 +189,82 @@ public class StandardQuotaStrategyTest
{
return FileUtils.listFiles(cacheRoot, new SuffixFileFilter(".bin"), TrueFileFilter.INSTANCE);
}
+
+
+ /**
+ * Not a unit test, but useful to fire up a lot of writers that will push the
+ * CachingContentStore's StandardQuotaStrategy beyond the panic threshold. The
+ * behaviour can then be monitored with, for example, a profiler.
+ *
+ * @throws Exception
+ */
+ private void concurrencySmokeTest() throws Exception
+ {
+ StandardQuotaStrategyTest.beforeClass();
+ setUp();
+ // Need to set maxDeleteWatch count to > 0
+ // (0 is useful in unit tests, but for real usage must not be used)
+ cleaner.setMaxDeleteWatchCount(1);
+
+ final int numThreads = 100;
+ Thread[] writers = new Thread[numThreads];
+ for (int i = 0; i < numThreads; i++)
+ {
+ final String threadName = "WriterThread[" + i + "]";
+ Runnable runnable = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ while (true)
+ {
+ writeFile();
+ pause();
+ }
+ }
+
+ private void writeFile()
+ {
+ try
+ {
+ writeSingleFileInMB(1);
+ }
+ catch (IOException error)
+ {
+ throw new RuntimeException(threadName + " couldn't write file.", error);
+ }
+ }
+
+ private void pause()
+ {
+ long pauseTimeMillis = Math.round(Math.random() * 2000);
+ try
+ {
+ Thread.sleep(pauseTimeMillis);
+ }
+ catch (InterruptedException error)
+ {
+ // Swallow the exception and carry on.
+ System.out.println(threadName + " InterruptedException.");
+ }
+ }
+ };
+ Thread writerThread = new Thread(runnable);
+ writerThread.setName(threadName);
+ writers[i] = writerThread;
+
+ writerThread.start();
+ }
+
+// StandardQuotaStrategyTest.afterClass();
+ }
+
+
+
+ public static void main(String[] args) throws Exception
+ {
+ StandardQuotaStrategyTest test = new StandardQuotaStrategyTest();
+ test.concurrencySmokeTest();
+ }
+
}
diff --git a/source/test-resources/cachingstore/test-std-quota-context.xml b/source/test-resources/cachingstore/test-std-quota-context.xml
index da9ee10404..07580f16fd 100644
--- a/source/test-resources/cachingstore/test-std-quota-context.xml
+++ b/source/test-resources/cachingstore/test-std-quota-context.xml
@@ -16,7 +16,7 @@
class="org.alfresco.repo.content.caching.quota.StandardQuotaStrategy"
init-method="init"
destroy-method="shutdown">
-
+