You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2014/04/30 18:17:09 UTC
svn commit: r1591384 - in /jackrabbit/oak/branches/1.0: ./
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
Author: mreutegg
Date: Wed Apr 30 16:17:09 2014
New Revision: 1591384
URL: http://svn.apache.org/r1591384
Log:
OAK-1784: Async index update persists conflict markers
Modified:
jackrabbit/oak/branches/1.0/ (props changed)
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
Merged /jackrabbit/oak/trunk:r1591381
Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java?rev=1591384&r1=1591383&r2=1591384&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java Wed Apr 30 16:17:09 2014
@@ -41,10 +41,15 @@ import org.apache.jackrabbit.oak.api.Com
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.api.jmx.IndexStatsMBean;
+import org.apache.jackrabbit.oak.plugins.commit.AnnotatingConflictHandler;
+import org.apache.jackrabbit.oak.plugins.commit.ConflictHook;
+import org.apache.jackrabbit.oak.plugins.commit.ConflictValidatorProvider;
import org.apache.jackrabbit.oak.plugins.value.Conversions;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.CompositeHook;
import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -228,7 +233,10 @@ public class AsyncIndexUpdate implements
private static CommitHook newCommitHook(final String name,
final PropertyState state) throws CommitFailedException {
- return new CommitHook() {
+ return new CompositeHook(
+ new ConflictHook(new AnnotatingConflictHandler()),
+ new EditorHook(new ConflictValidatorProvider()),
+ new CommitHook() {
@Override
@Nonnull
public NodeState processCommit(NodeState before, NodeState after,
@@ -243,7 +251,7 @@ public class AsyncIndexUpdate implements
throw CONCURRENT_UPDATE;
}
}
- };
+ });
}
private static void preAsyncRun(NodeStore store, String name) throws CommitFailedException {
Modified: jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java?rev=1591384&r1=1591383&r2=1591384&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java Wed Apr 30 16:17:09 2014
@@ -24,24 +24,32 @@ import static org.apache.jackrabbit.oak.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
import java.util.Collections;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
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.MemoryNodeStore;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -273,4 +281,76 @@ public class AsyncIndexUpdateTest {
assertFalse(store.getRoot().hasChildNode("child"));
}
+
+ // OAK-1784
+ @Test
+ public void failOnConflict() throws Exception {
+ final Map<Thread, Semaphore> locks = Maps.newIdentityHashMap();
+ NodeStore store = new MemoryNodeStore() {
+ @Nonnull
+ @Override
+ public NodeState merge(@Nonnull NodeBuilder builder,
+ @Nonnull CommitHook commitHook,
+ @Nullable CommitInfo info)
+ throws CommitFailedException {
+ Semaphore s = locks.get(Thread.currentThread());
+ if (s != null) {
+ s.acquireUninterruptibly();
+ }
+ return super.merge(builder, commitHook, info);
+ }
+ };
+ IndexEditorProvider provider = new PropertyIndexEditorProvider();
+
+ NodeBuilder builder = store.getRoot().builder();
+ createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo",
+ false, ImmutableSet.of("foo"), null, TYPE,
+ Collections.singletonMap(ASYNC_PROPERTY_NAME, "async"));
+
+ builder.child("test").setProperty("foo", "a");
+
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ final AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider);
+ async.run();
+
+ builder = store.getRoot().builder();
+ builder.child("test").setProperty("foo", "b");
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ async.run();
+ }
+ });
+ Semaphore s = new Semaphore(0);
+ locks.put(t, s);
+ t.start();
+
+ while (!s.hasQueuedThreads()) {
+ // busy wait
+ }
+
+ // introduce a conflict
+ builder = store.getRoot().builder();
+ builder.getChildNode(INDEX_DEFINITIONS_NAME).getChildNode("foo")
+ .getChildNode(":index").child("a").remove();
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ s.release(100);
+ t.join();
+
+ builder = store.getRoot().builder();
+ assertNoConflictMarker(builder);
+ }
+
+ private void assertNoConflictMarker(NodeBuilder builder) {
+ for (String name : builder.getChildNodeNames()) {
+ if (name.equals(ConflictAnnotatingRebaseDiff.CONFLICT)) {
+ fail("conflict marker detected");
+ }
+ assertNoConflictMarker(builder.getChildNode(name));
+ }
+ }
}