Author: chetanm
Date: Mon Nov 30 05:15:48 2015
New Revision: 1717177
URL: http://svn.apache.org/viewvc?rev=1717177&view=rev
Log:
OAK-3689 - OakOSGiRepositoryFactory shutting down the repository twice
Fixed another case where if shutdown is invoked multiple times (due to some
host application issue) then it would trigger a wait on latch which would not
be countdown and shutdown logic would wait for timeout.
Now the shutdown call would maintain a state to determine if shutdown is
initiated. If not already done it would initiate the shutdown otherwise the
call would be ignored
Modified:
jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/RepositoryShutdownTest.groovy
Modified:
jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java?rev=1717177&r1=1717176&r2=1717177&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
(original)
+++
jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
Mon Nov 30 05:15:48 2015
@@ -33,6 +33,7 @@ import java.util.concurrent.CountDownLat
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
@@ -274,7 +275,12 @@ public class OakOSGiRepositoryFactory im
//Wait for framework shutdown to complete
try {
- shutdownLatch.await(timeoutInSecs, TimeUnit.SECONDS);
+ boolean shutdownWithinTimeout = shutdownLatch.await(timeoutInSecs,
+ TimeUnit.SECONDS);
+ if (!shutdownWithinTimeout){
+ throw new BundleException("Timed out while waiting for
repository " +
+ "shutdown for "+ timeoutInSecs + " secs");
+ }
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new BundleException("Timed out while waiting for repository
" +
@@ -446,6 +452,7 @@ public class OakOSGiRepositoryFactory im
private static class RepositoryProxy implements InvocationHandler {
private final RepositoryTracker tracker;
private Repository initialService;
+ private final AtomicBoolean shutdownInitiated = new AtomicBoolean();
private RepositoryProxy(RepositoryTracker tracker, Repository
initialService) {
this.tracker = tracker;
@@ -464,7 +471,9 @@ public class OakOSGiRepositoryFactory im
//Repository would be shutdown by the owning OSGi
//component like RepositoryManager
if ("shutdown".equals(name)) {
- tracker.shutdownRepository();
+ if (!shutdownInitiated.getAndSet(true)) {
+ tracker.shutdownRepository();
+ }
return null;
}
Modified:
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/RepositoryShutdownTest.groovy
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/RepositoryShutdownTest.groovy?rev=1717177&r1=1717176&r2=1717177&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/RepositoryShutdownTest.groovy
(original)
+++
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/RepositoryShutdownTest.groovy
Mon Nov 30 05:15:48 2015
@@ -43,10 +43,31 @@ class RepositoryShutdownTest {
@Test
public void multipleShutdown() throws Exception{
JackrabbitRepository repository = mock(JackrabbitRepository.class)
+ def config = getConfig(repository)
+
+ Repository repo2 = new OakOSGiRepositoryFactory().getRepository(config)
+ assert repo2 instanceof JackrabbitRepository
+ repo2.shutdown()
+
+ verify(repository, times(0)).shutdown()
+ }
+
+ @Test
+ public void multipleShutdownAndWait() throws Exception{
+ JackrabbitRepository repository = mock(JackrabbitRepository.class)
+ def config = getConfig(repository)
+
+ Repository repo2 = new OakOSGiRepositoryFactory().getRepository(config)
+ assert repo2 instanceof JackrabbitRepository
+ repo2.shutdown()
+ repo2.shutdown()
+ }
+
+ private LinkedHashMap<String, Object> getConfig(repository) {
def config = [
- (REPOSITORY_HOME): tmpFolder.root.absolutePath,
- (REPOSITORY_TIMEOUT_IN_SECS) : 60,
- (BundleActivator.class.name) : new BundleActivator(){
+ (REPOSITORY_HOME) : tmpFolder.root.absolutePath,
+ (REPOSITORY_TIMEOUT_IN_SECS): 1,
+ (BundleActivator.class.name): new BundleActivator() {
@Override
void start(BundleContext bundleContext) throws Exception {
bundleContext.registerService(Repository.class.name,
repository, null)
@@ -58,12 +79,6 @@ class RepositoryShutdownTest {
}
}
]
-
- Repository repo2 = new OakOSGiRepositoryFactory().getRepository(config)
- assert repo2 instanceof JackrabbitRepository
- repo2.shutdown()
-
- verify(repository, times(0)).shutdown()
-
+ config
}
}