Author: chetanm
Date: Wed Nov 23 06:16:24 2016
New Revision: 1770914

URL: http://svn.apache.org/viewvc?rev=1770914&view=rev
Log:
OAK-4939 - Isolate corrupted index and make async indexer more resilient

Make corrupt index timeout configurable via OSGi. By default any index failing 
for 30 mins would considered as corrupted. Setting 'failingIndexTimeoutSeconds' 
to 0 would disable corrupt index handling logic altogether

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerService.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerServiceTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerService.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerService.java?rev=1770914&r1=1770913&r2=1770914&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerService.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerService.java
 Wed Nov 23 06:16:24 2016
@@ -73,6 +73,15 @@ public class AsyncIndexerService {
     )
     private static final String PROP_LEASE_TIME_OUT = "leaseTimeOutMinutes";
 
+    private static final long PROP_FAILING_INDEX_TIMEOUT_DEFAULT = 30 * 60;
+    @Property(
+            longValue = PROP_FAILING_INDEX_TIMEOUT_DEFAULT,
+            label = "Failing Index Timeout (s)",
+            description = "Time interval in seconds after which a failing 
index is considered as corrupted and " +
+                    "ignored from further indexing untill reindex. To disable 
this set it to 0"
+    )
+    private static final String PROP_FAILING_INDEX_TIMEOUT = 
"failingIndexTimeoutSeconds";
+
     private static final char CONFIG_SEP = ':';
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final WhiteboardIndexEditorProvider indexEditorProvider = new 
WhiteboardIndexEditorProvider();
@@ -103,11 +112,15 @@ public class AsyncIndexerService {
             log.info("Detected non clusterable setup. Lease checking would be 
disabled for async indexing");
         }
 
+        TrackingCorruptIndexHandler corruptIndexHandler = 
createCorruptIndexHandler(config);
+
         for (AsyncConfig c : asyncIndexerConfig) {
             AsyncIndexUpdate task = new AsyncIndexUpdate(c.name, nodeStore, 
indexEditorProvider,
                     statisticsProvider, false);
+            task.setCorruptIndexHandler(corruptIndexHandler);
             
task.setValidatorProviders(Collections.singletonList(validatorProvider));
             task.setLeaseTimeOut(TimeUnit.MINUTES.toMillis(leaseTimeOutMin));
+
             indexRegistration.registerAsyncIndexer(task, c.timeIntervalInSecs);
         }
         log.info("Configured async indexers {} ", asyncIndexerConfig);
@@ -123,6 +136,23 @@ public class AsyncIndexerService {
 
     //~-------------------------------------------< internal >
 
+    private TrackingCorruptIndexHandler createCorruptIndexHandler(Map<String, 
Object> config) {
+        long failingIndexTimeoutSeconds = 
PropertiesUtil.toLong(config.get(PROP_FAILING_INDEX_TIMEOUT),
+                PROP_FAILING_INDEX_TIMEOUT_DEFAULT);
+
+        TrackingCorruptIndexHandler corruptIndexHandler = new 
TrackingCorruptIndexHandler();
+        corruptIndexHandler.setCorruptInterval(failingIndexTimeoutSeconds, 
TimeUnit.SECONDS);
+
+        if (failingIndexTimeoutSeconds <= 0){
+            log.info("[{}] is set to {}. Auto corrupt index isolation handling 
is disabled,",
+                    PROP_FAILING_INDEX_TIMEOUT, failingIndexTimeoutSeconds);
+        } else {
+            log.info("Auto corrupt index isolation handling is enabled. Any 
async index which fails for [{}]s would " +
+                    "be marked as corrupted and would be skipped from further 
indexing");
+        }
+        return corruptIndexHandler;
+    }
+
     static List<AsyncConfig> getAsyncConfig(String[] configs) {
         List<AsyncConfig> result = Lists.newArrayList();
         for (String config : configs) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerServiceTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerServiceTest.java?rev=1770914&r1=1770913&r2=1770914&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerServiceTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexerServiceTest.java
 Wed Nov 23 06:16:24 2016
@@ -142,6 +142,18 @@ public class AsyncIndexerServiceTest {
         assertEquals(23, configs.get(1).timeIntervalInSecs);
     }
 
+    @Test
+    public void corruptIndexTimeout() throws Exception{
+        injectDefaultServices();
+        Map<String,Object> config = ImmutableMap.<String, Object>of(
+                "asyncConfigs", new String[] {"async:5"},
+                "failingIndexTimeoutSeconds" , "43"
+        );
+        MockOsgi.activate(service, context.bundleContext(), config);
+        AsyncIndexUpdate indexUpdate = getIndexUpdate("async");
+        assertEquals(TimeUnit.SECONDS.toMillis(43), 
indexUpdate.getCorruptIndexHandler().getCorruptIntervalMillis());
+    }
+
     private void injectDefaultServices() {
         context.registerService(StatisticsProvider.class, 
StatisticsProvider.NOOP);
         context.registerService(NodeStore.class, nodeStore);


Reply via email to