Author: chetanm
Date: Tue Oct  3 05:09:14 2017
New Revision: 1810642

URL: http://svn.apache.org/viewvc?rev=1810642&view=rev
Log:
OAK-6535 - Synchronous Lucene Property Indexes

Register cleaner job with default frequency of 10 mins

Modified:
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java?rev=1810642&r1=1810641&r2=1810642&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
 Tue Oct  3 05:09:14 2017
@@ -36,6 +36,7 @@ import javax.annotation.Nonnull;
 import javax.management.NotCompliantMBeanException;
 
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.felix.scr.annotations.Activate;
@@ -66,6 +67,7 @@ import org.apache.jackrabbit.oak.plugins
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.LocalIndexObserver;
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.LuceneJournalPropertyService;
 import org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.NRTIndexFactory;
+import 
org.apache.jackrabbit.oak.plugins.index.lucene.property.PropertyIndexCleaner;
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.reader.DefaultIndexReaderFactory;
 import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
 import org.apache.jackrabbit.oak.spi.commit.BackgroundObserver;
@@ -249,6 +251,16 @@ public class LuceneIndexProviderService
                     "Cleanup implies purging index blobs marked as deleted 
earlier during some indexing cycle."
     )
     private static final String 
PROP_NAME_DELETED_BLOB_COLLECTION_DEFAULT_INTERVAL = 
"deletedBlobsCollectionInterval";
+
+    private static final int PROP_INDEX_CLEANER_INTERVAL_DEFAULT = 10*60;
+    @Property(
+            intValue = PROP_INDEX_CLEANER_INTERVAL_DEFAULT,
+            label = "Property Index Cleaner Interval (seconds)",
+            description = "Cleaner interval time (in seconds) for synchronous 
property indexes configured as " +
+                    "part of lucene indexes"
+    )
+    private static final String PROP_INDEX_CLEANER_INTERVAL = 
"propIndexCleanerIntervalInSecs";
+
     /**
      * Actively deleted blob must be deleted for at least this long (in 
seconds)
      */
@@ -369,6 +381,7 @@ public class LuceneIndexProviderService
         registerIndexEditor(bundleContext, tracker, config);
         registerIndexInfoProvider(bundleContext);
         registerIndexImporterProvider(bundleContext);
+        registerPropertyIndexCleaner(config, bundleContext);
 
         oakRegs.add(registerMBean(whiteboard,
                 LuceneIndexMBean.class,
@@ -763,6 +776,24 @@ public class LuceneIndexProviderService
         return timestamp;
     }
 
+
+    private void registerPropertyIndexCleaner(Map<String, ?> config, 
BundleContext bundleContext) {
+        int cleanerInterval = 
PropertiesUtil.toInteger(config.get(PROP_INDEX_CLEANER_INTERVAL),
+                PROP_INDEX_CLEANER_INTERVAL_DEFAULT);
+
+        if (cleanerInterval <= 0) {
+            log.info("Property index cleaner would not be registered");
+            return;
+        }
+
+        PropertyIndexCleaner cleaner = new PropertyIndexCleaner(nodeStore, 
indexPathService, asyncIndexInfoService);
+        oakRegs.add(scheduleWithFixedDelay(whiteboard, cleaner,
+                ImmutableMap.of("scheduler.name", 
PropertyIndexCleaner.class.getName()),
+                cleanerInterval, true, true));
+        log.info("Property index cleaner configured to run every [{}] 
seconds", cleanerInterval);
+    }
+
+
     protected void bindNodeAggregator(QueryIndex.NodeAggregator aggregator) {
         this.nodeAggregator = aggregator;
         initialize();

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java?rev=1810642&r1=1810641&r2=1810642&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
 Tue Oct  3 05:09:14 2017
@@ -53,7 +53,7 @@ import static org.apache.jackrabbit.oak.
 import static 
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.STORAGE_TYPE_UNIQUE;
 import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.getNode;
 
-public class PropertyIndexCleaner {
+public class PropertyIndexCleaner implements Runnable{
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final NodeStore nodeStore;
     private final IndexPathService indexPathService;
@@ -63,9 +63,18 @@ public class PropertyIndexCleaner {
 
     public PropertyIndexCleaner(NodeStore nodeStore, IndexPathService 
indexPathService,
                                 AsyncIndexInfoService asyncIndexInfoService) {
-        this.nodeStore = nodeStore;
-        this.indexPathService = indexPathService;
-        this.asyncIndexInfoService = asyncIndexInfoService;
+        this.nodeStore = checkNotNull(nodeStore);
+        this.indexPathService = checkNotNull(indexPathService);
+        this.asyncIndexInfoService = checkNotNull(asyncIndexInfoService);
+    }
+
+    @Override
+    public void run() {
+        try{
+            performCleanup();
+        } catch (Exception e) {
+            log.warn("Cleanup run failed with error", e);
+        }
     }
 
     /**
@@ -73,7 +82,7 @@ public class PropertyIndexCleaner {
      *
      * @return true if the cleanup was attempted
      */
-    public boolean run() throws CommitFailedException {
+    public boolean performCleanup() throws CommitFailedException {
         Stopwatch w = Stopwatch.createStarted();
         Map<String, Long> asyncInfo = getAsyncInfo();
         if (lastAsyncInfo.equals(asyncInfo)) {

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java?rev=1810642&r1=1810641&r2=1810642&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
 Tue Oct  3 05:09:14 2017
@@ -38,6 +38,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
 import org.apache.jackrabbit.oak.api.jmx.CheckpointMBean;
+import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
 import org.apache.jackrabbit.oak.plugins.blob.datastore.CachingFileDataStore;
 import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore;
 import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreUtils;
@@ -47,6 +48,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.index.IndexPathService;
 import 
org.apache.jackrabbit.oak.plugins.index.fulltext.PreExtractedTextProvider;
 import org.apache.jackrabbit.oak.plugins.index.importer.IndexImporterProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.lucene.property.PropertyIndexCleaner;
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.directory.BufferedOakDirectory;
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.score.ScorerProviderFactory;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
@@ -57,6 +59,8 @@ import org.apache.jackrabbit.oak.spi.mou
 import org.apache.jackrabbit.oak.spi.mount.Mounts;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.util.InfoStream;
@@ -84,6 +88,8 @@ public class LuceneIndexProviderServiceT
 
     private LuceneIndexProviderService service = new 
LuceneIndexProviderService();
 
+    private Whiteboard wb;
+
     @Before
     public void setUp(){
         context.registerService(MountInfoProvider.class, 
Mounts.defaultMountInfoProvider());
@@ -94,6 +100,8 @@ public class LuceneIndexProviderServiceT
         context.registerService(IndexPathService.class, 
mock(IndexPathService.class));
         context.registerService(AsyncIndexInfoService.class, 
mock(AsyncIndexInfoService.class));
         context.registerService(CheckpointMBean.class, 
mock(CheckpointMBean.class));
+
+        wb = new OsgiWhiteboard(context.bundleContext());
         MockOsgi.injectServices(service, context.bundleContext());
     }
 
@@ -133,6 +141,8 @@ public class LuceneIndexProviderServiceT
         assertNotNull(context.getService(JournalPropertyService.class));
         assertNotNull(context.getService(IndexImporterProvider.class));
 
+        assertNotNull(WhiteboardUtils.getServices(wb, Runnable.class, r -> r 
instanceof PropertyIndexCleaner));
+
         MockOsgi.deactivate(service, context.bundleContext());
     }
 
@@ -331,7 +341,30 @@ public class LuceneIndexProviderServiceT
         assertFalse("Enabling property must reflect in BufferedOakDirectory 
state",
                 BufferedOakDirectory.isEnableWritingSingleBlobIndexFile());
         MockOsgi.deactivate(service, context.bundleContext());
+    }
 
+    @Test
+    public void cleanerRegistration() throws Exception{
+        Map<String,Object> config = getDefaultConfig();
+        config.put("propIndexCleanerIntervalInSecs", 142);
+
+        MockOsgi.activate(service, context.bundleContext(), config);
+        ServiceReference[] sr = 
context.bundleContext().getAllServiceReferences(Runnable.class.getName(),
+                "(scheduler.name="+PropertyIndexCleaner.class.getName()+")");
+        assertEquals(sr.length, 1);
+
+        assertEquals(142L, sr[0].getProperty("scheduler.period"));
+    }
+
+    @Test
+    public void cleanerRegistrationDisabled() throws Exception{
+        Map<String,Object> config = getDefaultConfig();
+        config.put("propIndexCleanerIntervalInSecs", 0);
+
+        MockOsgi.activate(service, context.bundleContext(), config);
+        ServiceReference[] sr = 
context.bundleContext().getAllServiceReferences(Runnable.class.getName(),
+                "(scheduler.name="+PropertyIndexCleaner.class.getName()+")");
+        assertNull(sr);
     }
 
     private void reactivate() {

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java?rev=1810642&r1=1810641&r2=1810642&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
 Tue Oct  3 05:09:14 2017
@@ -115,7 +115,7 @@ public class PropertyIndexCleanerTest {
 
         //------------------------ Run 1
         asyncService.addInfo("async", 1000);
-        assertTrue(cleaner.run());
+        assertTrue(cleaner.performCleanup());
 
         assertThat(query(indexPath, "foo", "bar"), containsInAnyOrder("/a"));
 
@@ -128,14 +128,14 @@ public class PropertyIndexCleanerTest {
 
         //------------------------ Run 2
         asyncService.addInfo("async", 2000);
-        assertTrue(cleaner.run());
+        assertTrue(cleaner.performCleanup());
 
         //Now /a would be part of removed bucket
         assertThat(query(indexPath, "foo", "bar"), containsInAnyOrder("/b"));
 
         //------------------------ Run 3
         asyncService.addInfo("async", 3000);
-        assertTrue(cleaner.run());
+        assertTrue(cleaner.performCleanup());
 
         //With another run /b would also be removed
         assertThat(query(indexPath, "foo", "bar"), empty());
@@ -173,7 +173,7 @@ public class PropertyIndexCleanerTest {
 
         //------------------------ Run 1
         asyncService.addInfo("async", 1200);
-        assertTrue(cleaner.run());
+        assertTrue(cleaner.performCleanup());
 
         // /a would be purged, /b would be retained as its created time 1150 
is not older than 100 wrt
         // indexer time of 1200
@@ -193,7 +193,7 @@ public class PropertyIndexCleanerTest {
 
         //------------------------ Run 2
         asyncService.addInfo("async", 1400);
-        assertTrue(cleaner.run());
+        assertTrue(cleaner.performCleanup());
 
         //Both entries would have been purged
         assertThat(query(indexPath, "foo", "bar"), empty());
@@ -219,10 +219,10 @@ public class PropertyIndexCleanerTest {
 
         //------------------------ Run 1
         asyncService.addInfo("async", 1000);
-        assertTrue(cleaner.run());
+        assertTrue(cleaner.performCleanup());
 
         //Second run should not run
-        assertFalse(cleaner.run());
+        assertFalse(cleaner.performCleanup());
     }
 
     private void addIndex(String indexPath, IndexDefinitionBuilder defnb) 
throws CommitFailedException {


Reply via email to