You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2013/05/15 11:08:54 UTC
svn commit: r1482732 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/
main/java/org/apache/jackrabbit/core/data/
test/java/org/apache/jackrabbit/core/data/
Author: thomasm
Date: Wed May 15 09:08:53 2013
New Revision: 1482732
URL: http://svn.apache.org/r1482732
Log:
JCR-3547 Datastore GC doesn't reset updateModifiedDateOnAccess on datastore
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java?rev=1482732&r1=1482731&r2=1482732&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java Wed May 15 09:08:53 2013
@@ -124,6 +124,12 @@ public class RepositoryContext {
* The Statistics manager, handles statistics
*/
private StatManager statManager;
+
+ /**
+ * flag to indicate if GC is running
+ */
+
+ private boolean gcRunning;
/**
* Creates a component context for the given repository.
@@ -450,4 +456,22 @@ public class RepositoryContext {
return statManager;
}
+ /**
+ *
+ * @return gcRunning status
+ */
+ public boolean isGcRunning() {
+ return gcRunning;
+ }
+
+ /**
+ * set gcRunnign status
+ * @param gcRunning
+ */
+ public synchronized void setGcRunning(boolean gcRunning) {
+ this.gcRunning = gcRunning;
+ }
+
+
+
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=1482732&r1=1482731&r2=1482732&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Wed May 15 09:08:53 2013
@@ -1423,7 +1423,14 @@ public class RepositoryImpl extends Abst
}
ipmList[i] = (IterablePersistenceManager) pm;
}
- return new GarbageCollector(context.getDataStore(), ipmList, sessions);
+ GarbageCollector gc = new GarbageCollector(context, context.getDataStore(), ipmList, sessions);
+ synchronized (this) {
+ if (context.isGcRunning()) {
+ throw new RepositoryException("Cannot create GC. GC already running");
+ }
+ context.setGcRunning(true);
+ }
+ return gc;
}
//-----------------------------------------------------------< Repository >
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java?rev=1482732&r1=1482731&r2=1482732&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java Wed May 15 09:08:53 2013
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.core.data;
import org.apache.jackrabbit.api.management.DataStoreGarbageCollector;
import org.apache.jackrabbit.api.management.MarkEventListener;
+import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.id.PropertyId;
@@ -103,6 +104,8 @@ public class GarbageCollector implements
private final SessionImpl[] sessionList;
private final AtomicBoolean closed = new AtomicBoolean();
+
+ private final RepositoryContext context;
private boolean persistenceManagerScan;
@@ -112,14 +115,17 @@ public class GarbageCollector implements
* Create a new garbage collector.
* This method is usually not called by the application, it is called
* by SessionImpl.createDataStoreGarbageCollector().
- *
+ *
+ * @param context repository context
* @param dataStore the data store to be garbage-collected
* @param list the persistence managers
* @param sessionList the sessions to access the workspaces
*/
- public GarbageCollector(
+
+ public GarbageCollector(RepositoryContext context,
DataStore dataStore, IterablePersistenceManager[] list,
SessionImpl[] sessionList) {
+ this.context = context;
this.store = dataStore;
this.pmList = list;
this.persistenceManagerScan = list != null;
@@ -226,9 +232,13 @@ public class GarbageCollector implements
}
/**
- * Stop the observation listener if any are installed.
+ * Reset modifiedDateOnAccess to 0 and stop the observation
+ * listener if any are installed.
*/
public void stopScan() throws RepositoryException {
+ // reset updateModifiedDateOnAccess to OL
+ store.updateModifiedDateOnAccess(0L);
+
if (listeners.size() > 0) {
for (Listener listener : listeners) {
listener.stop();
@@ -236,6 +246,7 @@ public class GarbageCollector implements
listeners.clear();
}
checkObservationException();
+ context.setGcRunning(false);
}
public int sweep() throws RepositoryException {
@@ -335,7 +346,7 @@ public class GarbageCollector implements
*/
}
- private void checkLengths(long... lengths) throws RepositoryException {
+ private static void checkLengths(long... lengths) throws RepositoryException {
for (long length : lengths) {
if (length == -1) {
throw new RepositoryException("mark failed to access a property");
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java?rev=1482732&r1=1482731&r2=1482732&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java Wed May 15 09:08:53 2013
@@ -56,7 +56,7 @@ public class GarbageCollectorTest extend
closeTest();
}
- private void closeTest() throws RepositoryException {
+ private void closeTest() {
if (closed) {
ex[0] = new Exception("Scanning after the session is closed");
}
@@ -183,6 +183,35 @@ public class GarbageCollectorTest extend
gc.close();
}
+
+ /**
+ * Test to validate that two GC cannot run simulatenously. one
+ * exits throwing exception
+ */
+ public void testSimulatenousRunGC() throws Exception {
+ Node root = testRootNode;
+ Session session = root.getSession();
+
+ GCThread gct1 = new GCThread(session);
+ GCThread gct2 = new GCThread(session);
+ Thread gcThread1 = new Thread(gct1, "Datastore Garbage Collector 1");
+ Thread gcThread2 = new Thread(gct2, "Datastore Garbage Collector 2");
+ // run simulatensou gc
+ gcThread1.start();
+ gcThread2.start();
+ Thread.sleep(100);
+
+ gct1.setStop(true);
+ gct2.setStop(true);
+
+ // allow them to complete
+ gcThread1.join();
+ gcThread2.join();
+
+ // only one should throw error
+ int count = (gct1.getException() == null ? 0 : 1) + (gct2.getException() == null ? 0 : 1);
+ assertEquals("only one gc should throw exception ", 1, count);
+ }
private void runGC(Session session, boolean all) throws Exception {
GarbageCollector gc = ((SessionImpl)session).createDataStoreGarbageCollector();
@@ -202,7 +231,7 @@ public class GarbageCollectorTest extend
gc.close();
}
- private int listIdentifiers(GarbageCollector gc) throws DataStoreException {
+ private static int listIdentifiers(GarbageCollector gc) throws DataStoreException {
LOG.debug("identifiers:");
int count = 0;
Iterator<DataIdentifier> it = gc.getDataStore().getAllIdentifiers();
@@ -242,7 +271,7 @@ public class GarbageCollectorTest extend
s2.logout();
}
- private void verifyInputStream(InputStream in, InputStream in2) throws IOException {
+ private static void verifyInputStream(InputStream in, InputStream in2) throws IOException {
while (true) {
int a = in.read();
int b = in2.read();