Author: alexparvulescu Date: Fri Oct 10 12:22:59 2014 New Revision: 1630773
URL: http://svn.apache.org/r1630773 Log: OAK-2174 Non-blocking reindexing doesn't finish properly Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java?rev=1630773&r1=1630772&r2=1630773&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java Fri Oct 10 12:22:59 2014 @@ -49,6 +49,7 @@ import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.io.Closer; + import org.apache.jackrabbit.oak.api.ContentRepository; import org.apache.jackrabbit.oak.api.ContentSession; import org.apache.jackrabbit.oak.api.Root; @@ -60,6 +61,7 @@ import org.apache.jackrabbit.oak.managem import org.apache.jackrabbit.oak.plugins.commit.ConflictHook; import org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate; import org.apache.jackrabbit.oak.plugins.index.CompositeIndexEditorProvider; +import org.apache.jackrabbit.oak.plugins.index.IndexConstants; import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider; import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider; import org.apache.jackrabbit.oak.plugins.index.property.jmx.PropertyIndexAsyncReindex; @@ -528,11 +530,11 @@ public class Oak { task.getIndexStats(), IndexStatsMBean.TYPE, name)); PropertyIndexAsyncReindex asyncPI = new PropertyIndexAsyncReindex( - new AsyncIndexUpdate("async-reindex", store, indexEditors, - true), getExecutor() - ); - regs.add(registerMBean(whiteboard, PropertyIndexAsyncReindexMBean.class, - asyncPI, PropertyIndexAsyncReindexMBean.TYPE, name)); + new AsyncIndexUpdate(IndexConstants.ASYNC_REINDEX_VALUE, + store, indexEditors, true), getExecutor()); + regs.add(registerMBean(whiteboard, + PropertyIndexAsyncReindexMBean.class, asyncPI, + PropertyIndexAsyncReindexMBean.TYPE, name)); } regs.add(registerMBean(whiteboard, QueryEngineSettingsMBean.class, Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java?rev=1630773&r1=1630772&r2=1630773&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java Fri Oct 10 12:22:59 2014 @@ -357,29 +357,30 @@ public class AsyncIndexUpdate implements } else { postAsyncRunStatsStatus(indexStats); } - } else if (switchOnSync) { - log.debug("No changes detected after diff; will try to" - + " switch to synchronous updates on {}", - reindexedDefinitions); - - // no changes after diff, switch to sync on the async defs - for (String path : reindexedDefinitions) { - NodeBuilder c = builder; - for (String p : elements(path)) { - c = c.getChildNode(p); - } - if (c.exists() && !c.getBoolean(REINDEX_PROPERTY_NAME)) { - c.removeProperty(ASYNC_PROPERTY_NAME); + } else { + if (switchOnSync) { + log.debug( + "No changes detected after diff; will try to switch to synchronous updates on {}", + reindexedDefinitions); + + // no changes after diff, switch to sync on the async defs + for (String path : reindexedDefinitions) { + NodeBuilder c = builder; + for (String p : elements(path)) { + c = c.getChildNode(p); + } + if (c.exists() && !c.getBoolean(REINDEX_PROPERTY_NAME)) { + c.removeProperty(ASYNC_PROPERTY_NAME); + } } + reindexedDefinitions.clear(); } - reindexedDefinitions.clear(); + postAsyncRunStatsStatus(indexStats); } mergeWithConcurrencyCheck(builder, beforeCheckpoint, callback.lease); } finally { callback.close(); } - - postAsyncRunStatsStatus(indexStats); } private void mergeWithConcurrencyCheck( Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java?rev=1630773&r1=1630772&r2=1630773&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java Fri Oct 10 12:22:59 2014 @@ -23,8 +23,8 @@ import static org.apache.jackrabbit.oak. import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition; import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider.TYPE; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Collections; @@ -443,6 +443,7 @@ public class AsyncIndexUpdateTest { // no changes on diff, no checkpoints left behind async.run(); + assertTrue(async.isFinished()); Set<String> checkpoints = newHashSet(store.listCheckpoints()); assertTrue("Expecting the initial checkpoint", checkpoints.size() == 1); Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java?rev=1630773&r1=1630772&r2=1630773&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java Fri Oct 10 12:22:59 2014 @@ -18,8 +18,11 @@ package org.apache.jackrabbit.oak.plugin import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM; import static org.apache.jackrabbit.JcrConstants.NT_BASE; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_REINDEX_VALUE; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_ASYNC_PROPERTY_NAME; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME; import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition; import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES; @@ -27,6 +30,7 @@ import static org.apache.jackrabbit.oak. import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Set; @@ -36,6 +40,7 @@ import org.apache.jackrabbit.oak.api.Typ import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider; import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexLookup; import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState; +import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; import org.apache.jackrabbit.oak.query.QueryEngineSettings; import org.apache.jackrabbit.oak.query.ast.SelectorImpl; import org.apache.jackrabbit.oak.query.index.FilterImpl; @@ -45,6 +50,7 @@ import org.apache.jackrabbit.oak.spi.que import org.apache.jackrabbit.oak.spi.query.PropertyValues; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.oak.spi.state.NodeStore; import org.junit.Test; import com.google.common.collect.ImmutableSet; @@ -289,6 +295,68 @@ public class IndexUpdateTest { } + + /** + * Async Reindex Test (OAK-2174) + * <ul> + * <li>Add some content</li> + * <li>Add an index definition with the reindex flag and the reindex-async flag set</li> + * <li>Run the background async job manually</li> + * <li>Search & verify</li> + * </ul> + */ + @Test + public void testReindexAsync() throws Exception { + IndexEditorProvider provider = new PropertyIndexEditorProvider(); + EditorHook hook = new EditorHook(new IndexUpdateProvider(provider)); + + NodeStore store = new MemoryNodeStore(); + NodeBuilder builder = store.getRoot().builder(); + + createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), + "rootIndex", true, false, ImmutableSet.of("foo"), null) + .setProperty(REINDEX_ASYNC_PROPERTY_NAME, true); + builder.child("testRoot").setProperty("foo", "abc"); + + // merge it back in + store.merge(builder, hook, CommitInfo.EMPTY); + + // first check that the async flag exist + NodeState ns1 = checkPathExists(store.getRoot(), + INDEX_DEFINITIONS_NAME, "rootIndex"); + assertTrue(ns1.getProperty(REINDEX_PROPERTY_NAME) + .getValue(Type.BOOLEAN)); + assertTrue(ns1.getProperty(REINDEX_ASYNC_PROPERTY_NAME).getValue( + Type.BOOLEAN)); + assertEquals(ASYNC_REINDEX_VALUE, ns1.getProperty(ASYNC_PROPERTY_NAME) + .getValue(Type.STRING)); + + AsyncIndexUpdate async = new AsyncIndexUpdate(ASYNC_REINDEX_VALUE, + store, provider, true); + int max = 5; + // same behaviour as PropertyIndexAsyncReindex mbean + boolean done = false; + int count = 0; + while (!done || count >= max) { + async.run(); + done = async.isFinished(); + count++; + } + + // first check that the index content nodes exist + NodeState ns = checkPathExists(store.getRoot(), INDEX_DEFINITIONS_NAME, + "rootIndex"); + checkPathExists(ns, INDEX_CONTENT_NODE_NAME); + assertFalse(ns.getProperty(REINDEX_PROPERTY_NAME) + .getValue(Type.BOOLEAN)); + assertNull(ns.getProperty(ASYNC_PROPERTY_NAME)); + + // next, lookup + PropertyIndexLookup lookup = new PropertyIndexLookup(store.getRoot()); + assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", + "abc")); + } + private Set<String> find(PropertyIndexLookup lookup, String name, String value) { NodeState system = root.getChildNode(JCR_SYSTEM);
