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
     }
 }


Reply via email to