You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2016/08/23 06:29:12 UTC

svn commit: r1757309 - in /jackrabbit/trunk/jackrabbit-vfs-ext/src: main/java/org/apache/jackrabbit/vfs/ext/ds/VFSBackend.java main/java/org/apache/jackrabbit/vfs/ext/ds/VFSDataStore.java test/java/org/apache/jackrabbit/vfs/ext/ds/TestVFSDataStore.java

Author: mreutegg
Date: Tue Aug 23 06:29:12 2016
New Revision: 1757309

URL: http://svn.apache.org/viewvc?rev=1757309&view=rev
Log:
JCR-4005: TestVFSDataStore.testDeleteRecord() fails occasionally

Apply patch by Woonsan Ko

Modified:
    jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSBackend.java
    jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSDataStore.java
    jackrabbit/trunk/jackrabbit-vfs-ext/src/test/java/org/apache/jackrabbit/vfs/ext/ds/TestVFSDataStore.java

Modified: jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSBackend.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSBackend.java?rev=1757309&r1=1757308&r2=1757309&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSBackend.java (original)
+++ jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSBackend.java Tue Aug 23 06:29:12 2016
@@ -27,6 +27,8 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadPoolExecutor;
 
@@ -94,7 +96,7 @@ public class VFSBackend implements Backe
     /**
      * Asynchronous write pooling executor.
      */
-    private ThreadPoolExecutor asyncWriteExecuter;
+    private Executor asyncWriteExecutor;
 
     /**
      * Whether or not a touch file is preferred to set/get the last modified timestamp for a file object
@@ -134,7 +136,7 @@ public class VFSBackend implements Backe
             touchFilePreferred = false;
         }
 
-        asyncWriteExecuter = createAsyncWriteExecuter();
+        asyncWriteExecutor = createAsyncWriteExecutor();
     }
 
     /**
@@ -205,7 +207,7 @@ public class VFSBackend implements Backe
             throw new IllegalArgumentException("callback parameter cannot be null in asyncUpload");
         }
 
-        getAsyncWriteExecuter().execute(new AsyncUploadJob(identifier, file, callback));
+        getAsyncWriteExecutor().execute(new AsyncUploadJob(identifier, file, callback));
     }
 
     /**
@@ -272,7 +274,7 @@ public class VFSBackend implements Backe
             throw new IllegalArgumentException("callback parameter cannot be null in touchAsync");
         }
 
-        getAsyncWriteExecuter().execute(new AsyncTouchJob(identifier, minModifiedDate, callback));
+        getAsyncWriteExecutor().execute(new AsyncTouchJob(identifier, minModifiedDate, callback));
     }
 
     /**
@@ -280,7 +282,11 @@ public class VFSBackend implements Backe
      */
     @Override
     public void close() throws DataStoreException {
-        getAsyncWriteExecuter().shutdownNow();
+        Executor asyncExecutor = getAsyncWriteExecutor();
+
+        if (asyncExecutor != null && asyncExecutor instanceof ExecutorService) {
+            ((ExecutorService) asyncExecutor).shutdownNow();
+        }
     }
 
     /**
@@ -454,17 +460,39 @@ public class VFSBackend implements Backe
      * This method is invoked during the initialization for asynchronous write/touch job executions.
      * @return a {@link ThreadPoolExecutor}
      */
-    protected ThreadPoolExecutor createAsyncWriteExecuter() {
-        return (ThreadPoolExecutor) Executors.newFixedThreadPool(asyncWritePoolSize,
-                new NamedThreadFactory("vfs-write-worker"));
+    protected Executor createAsyncWriteExecutor() {
+        Executor asyncExecutor;
+
+        if (getAsyncWritePoolSize() > 0) {
+            asyncExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(getAsyncWritePoolSize(),
+                    new NamedThreadFactory("vfs-write-worker"));
+        } else {
+            asyncExecutor = new ImmediateExecutor();
+        }
+
+        return asyncExecutor;
     }
 
     /**
      * Returns ThreadPoolExecutor used to execute asynchronous write or touch jobs.
      * @return ThreadPoolExecutor used to execute asynchronous write or touch jobs
      */
-    protected ThreadPoolExecutor getAsyncWriteExecuter() {
-        return asyncWriteExecuter;
+    protected Executor getAsyncWriteExecutor() {
+        return asyncWriteExecutor;
+    }
+
+    /**
+     * Returns the approximate number of threads that are actively executing asynchronous writing tasks.
+     * @return the approximate number of threads that are actively executing asynchronous writing tasks
+     */
+    protected int getAsyncWriteExecutorActiveCount() {
+        Executor asyncExecutor = getAsyncWriteExecutor();
+
+        if (asyncExecutor != null && asyncExecutor instanceof ThreadPoolExecutor) {
+            return ((ThreadPoolExecutor) asyncExecutor).getActiveCount();
+        }
+
+        return 0;
     }
 
     /**
@@ -769,6 +797,17 @@ public class VFSBackend implements Backe
         }
     }
 
+    /**
+     * This class implements {@link Executor} interface to run {@code command} right away,
+     * resulting in non-asynchronous mode executions.
+     */
+    private class ImmediateExecutor implements Executor {
+        @Override
+        public void execute(Runnable command) {
+            command.run();
+        }
+    }
+
     /**
      * This class implements {@link Runnable} interface to copy {@link File} to VFS file object asynchronously.
      */

Modified: jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSDataStore.java?rev=1757309&r1=1757308&r2=1757309&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSDataStore.java (original)
+++ jackrabbit/trunk/jackrabbit-vfs-ext/src/main/java/org/apache/jackrabbit/vfs/ext/ds/VFSDataStore.java Tue Aug 23 06:29:12 2016
@@ -45,6 +45,12 @@ import org.slf4j.LoggerFactory;
  */
 public class VFSDataStore extends CachingDataStore {
 
+    static final String BASE_FOLDER_URI = "baseFolderUri";
+
+    static final String ASYNC_WRITE_POOL_SIZE = "asyncWritePoolSize";
+
+    static final String FILE_SYSTEM_MANAGER_CLASS_NAME = "fileSystemManagerClassName";
+
     /**
      * Logger instance.
      */
@@ -146,7 +152,7 @@ public class VFSDataStore extends Cachin
         try {
             // Let's wait for 5 minutes at max if there are still execution jobs in the async writing executor's queue.
             int seconds = 0;
-            while (backend.getAsyncWriteExecuter().getActiveCount() > 0 && seconds++ < 300) {
+            while (backend.getAsyncWriteExecutorActiveCount() > 0 && seconds++ < 300) {
                 Thread.sleep(1000);
             }
         } catch (InterruptedException e) {
@@ -377,17 +383,17 @@ public class VFSDataStore extends Cachin
             try {
                 final Properties props = readConfig(config);
 
-                String propValue = props.getProperty("asyncWritePoolSize");
+                String propValue = props.getProperty(ASYNC_WRITE_POOL_SIZE);
                 if (propValue != null && !"".equals(propValue)) {
                     setAsyncWritePoolSize(Integer.parseInt(propValue));
                 }
 
-                propValue = props.getProperty("baseFolderUri");
+                propValue = props.getProperty(BASE_FOLDER_URI);
                 if (propValue != null && !"".equals(propValue)) {
                     setBaseFolderUri(propValue);
                 }
 
-                propValue = props.getProperty("fileSystemManagerClassName");
+                propValue = props.getProperty(FILE_SYSTEM_MANAGER_CLASS_NAME);
                 if (propValue != null && !"".equals(propValue)) {
                     setFileSystemManagerClassName(propValue);
                 }

Modified: jackrabbit/trunk/jackrabbit-vfs-ext/src/test/java/org/apache/jackrabbit/vfs/ext/ds/TestVFSDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-vfs-ext/src/test/java/org/apache/jackrabbit/vfs/ext/ds/TestVFSDataStore.java?rev=1757309&r1=1757308&r2=1757309&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-vfs-ext/src/test/java/org/apache/jackrabbit/vfs/ext/ds/TestVFSDataStore.java (original)
+++ jackrabbit/trunk/jackrabbit-vfs-ext/src/test/java/org/apache/jackrabbit/vfs/ext/ds/TestVFSDataStore.java Tue Aug 23 06:29:12 2016
@@ -56,11 +56,6 @@ public class TestVFSDataStore extends Te
      */
     private static final Logger LOG = LoggerFactory.getLogger(TestVFSDataStore.class);
 
-    /**
-     * VFS base folder URI configuration property key name.
-     */
-    private static final String BASE_FOLDER_URI = "baseFolderUri";
-
     private static final String FILE_SYSTEM_OPTIONS_PARAM_XML =
             "<param "
             + "name=\"fileSystemOptionsPropertiesInString\" "
@@ -75,19 +70,6 @@ public class TestVFSDataStore extends Te
     private Properties configProps;
 
     @Override
-    public void testDeleteRecord() {
-        // ignored, see JCR-4005
-        if (true) {
-            try {
-                createDataStore();
-            } catch (RepositoryException ignore) {
-            }
-            return;
-        }
-        super.testDeleteRecord();
-    }
-
-    @Override
     protected void setUp() throws Exception {
         super.setUp();
 
@@ -118,9 +100,14 @@ public class TestVFSDataStore extends Te
     protected CachingDataStore createDataStore() throws RepositoryException {
         dataStore = new VFSDataStore();
         Properties props = getConfigProps();
-        baseFolderUri = props.getProperty(BASE_FOLDER_URI);
+        baseFolderUri = props.getProperty(VFSDataStore.BASE_FOLDER_URI);
         dataStore.setBaseFolderUri(baseFolderUri);
         LOG.info("baseFolderUri [{}] set.", baseFolderUri);
+        String value = props.getProperty(VFSDataStore.ASYNC_WRITE_POOL_SIZE);
+        if (value != null) {
+            dataStore.setAsyncWritePoolSize(Integer.parseInt(value));
+            LOG.info("asyncWritePoolSize [{}] set.", dataStore.getAsyncWritePoolSize());
+        }
         dataStore.setFileSystemOptionsProperties(props);
         dataStore.setSecret("123456");
         dataStore.init(dataStoreDir);
@@ -136,7 +123,7 @@ public class TestVFSDataStore extends Te
         try {
             // Let's wait for 5 minutes at max if there are still execution jobs in the async writing executor's queue.
             int seconds = 0;
-            while (backend.getAsyncWriteExecuter().getActiveCount() > 0 && seconds++ < 300) {
+            while (backend.getAsyncWriteExecutorActiveCount() > 0 && seconds++ < 300) {
                 Thread.sleep(1000);
             }
 
@@ -172,7 +159,7 @@ public class TestVFSDataStore extends Te
     protected void doSetFileSystemOptionsPropertiesInString() throws Exception {
         dataStore = new VFSDataStore();
         Properties props = getConfigProps();
-        baseFolderUri = props.getProperty(BASE_FOLDER_URI);
+        baseFolderUri = props.getProperty(VFSDataStore.BASE_FOLDER_URI);
         dataStore.setBaseFolderUri(baseFolderUri);
         LOG.info("baseFolderUri [{}] set.", baseFolderUri);
         dataStore.setFileSystemOptionsProperties(props);
@@ -204,7 +191,9 @@ public class TestVFSDataStore extends Te
         if (configProps == null) {
             Properties props = new Properties();
             String baseFolderUri = new File(new File(dataStoreDir), "vfsds").toURI().toString();
-            props.setProperty(BASE_FOLDER_URI, baseFolderUri);
+            props.setProperty(VFSDataStore.BASE_FOLDER_URI, baseFolderUri);
+            // By default (when testing with local file system), disable asynchronous writing to the backend.
+            props.setProperty(VFSDataStore.ASYNC_WRITE_POOL_SIZE, "0");
             configProps = props;
         }