Author: mreutegg
Date: Mon Nov 25 09:43:55 2013
New Revision: 1545190
URL: http://svn.apache.org/r1545190
Log:
OAK-1202: Retry Persisted merge
- Introduced a MERGE type in CommitFailedException to distinguish it from other
commit failures
- Make sure KernelNodeStoreBranch throws appropriate exceptions on failures
- Leverage MicroKernel.reset() when Persisted.merge() fails
- Introduced a new branch state ResetFailed when the branch cannot be reset
- Moved the retry logic to AbstractNodeStoreBranch
- Removed the now duplicate retry logic in MongoNodeStoreBranch
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MergeRetryTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java
Mon Nov 25 09:43:55 2013
@@ -99,6 +99,11 @@ public class CommitFailedException exten
public static final String LABEL_EXISTS = "LabelExists";
/**
+ * Type name for merge errors.
+ */
+ public static final String MERGE = "Merge";
+
+ /**
* Unsupported operation or feature
*/
public static final String UNSUPPORTED = "Unsupported";
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
Mon Nov 25 09:43:55 2013
@@ -264,4 +264,9 @@ public class KernelNodeStore implements
KernelNodeState merge(KernelNodeState branchHead) {
return getRootState(kernel.merge(branchHead.getRevision(), null));
}
+
+ KernelNodeState reset(KernelNodeState branchHead, KernelNodeState
ancestor) {
+ return getRootState(kernel.reset(
+ branchHead.getRevision(), ancestor.getRevision()));
+ }
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
Mon Nov 25 09:43:55 2013
@@ -33,6 +33,7 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeState;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.MERGE;
/**
* {@code NodeStoreBranch} based on {@link MicroKernel} branching and merging.
@@ -90,8 +91,21 @@ public class KernelNodeStoreBranch exten
@Override
protected KernelNodeState merge(KernelNodeState branchHead,
- CommitInfo info) {
- return store.merge(branchHead);
+ CommitInfo info)
+ throws CommitFailedException {
+ try {
+ return store.merge(branchHead);
+ } catch (MicroKernelException e) {
+ throw new CommitFailedException(MERGE, 1,
+ "Failed to merge changes to the underlying MicroKernel",
e);
+ }
+ }
+
+ @Nonnull
+ @Override
+ protected KernelNodeState reset(@Nonnull KernelNodeState branchHead,
+ @Nonnull KernelNodeState ancestor) {
+ return store.reset(branchHead, ancestor);
}
@Override
@@ -127,8 +141,7 @@ public class KernelNodeStoreBranch exten
try {
return super.merge(hook, info);
} catch (MicroKernelException e) {
- throw new CommitFailedException(
- "Kernel", 1,
+ throw new CommitFailedException(MERGE, 1,
"Failed to merge changes to the underlying MicroKernel",
e);
} finally {
mergeLock.unlock();
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
Mon Nov 25 09:43:55 2013
@@ -37,6 +37,7 @@ import org.apache.jackrabbit.mk.json.Jso
import org.apache.jackrabbit.mk.json.JsopStream;
import org.apache.jackrabbit.mk.json.JsopTokenizer;
import org.apache.jackrabbit.mk.json.JsopWriter;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.cache.CacheLIRS;
import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.cache.CacheValue;
@@ -434,7 +435,11 @@ public class MongoMK implements MicroKer
if (!revision.isBranch()) {
throw new MicroKernelException("Not a branch: " +
branchRevisionId);
}
- return nodeStore.merge(revision, null).toString();
+ try {
+ return nodeStore.merge(revision, null).toString();
+ } catch (CommitFailedException e) {
+ throw new MicroKernelException(e.getMessage(), e);
+ }
}
@Override
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
Mon Nov 25 09:43:55 2013
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.MERGE;
import java.io.Closeable;
import java.io.IOException;
@@ -799,11 +800,11 @@ public final class MongoNodeStore
UpdateOp rootOp = commit.getUpdateOperationForNode("/");
// clear collisions
Iterator<Revision> it =
b.getCommits().tailSet(ancestor).iterator();
- // first revision is the ancestor
+ // first revision is the ancestor (tailSet is inclusive)
// do not clear collision for this revision
it.next();
while (it.hasNext()) {
- NodeDocument.unsetCollision(rootOp, it.next());
+ NodeDocument.removeCollision(rootOp, it.next());
}
rev = apply(commit);
success = true;
@@ -818,7 +819,8 @@ public final class MongoNodeStore
}
@Nonnull
- Revision merge(@Nonnull Revision branchHead, @Nullable CommitInfo info) {
+ Revision merge(@Nonnull Revision branchHead, @Nullable CommitInfo info)
+ throws CommitFailedException {
Branch b = getBranches().getBranch(branchHead);
Revision base = branchHead;
if (b != null) {
@@ -842,8 +844,8 @@ public final class MongoNodeStore
b.applyTo(getPendingModifications(), commit.getRevision());
getBranches().remove(b);
} else {
- // TODO: use non-MK exception type
- throw new MicroKernelException("Conflicting concurrent
change. Update operation failed: " + op);
+ throw new CommitFailedException(MERGE, 2,
+ "Conflicting concurrent change. Update operation
failed: " + op);
}
} else {
// no commits in this branch -> do nothing
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
Mon Nov 25 09:43:55 2013
@@ -17,12 +17,9 @@
package org.apache.jackrabbit.oak.plugins.mongomk;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.apache.jackrabbit.mk.api.MicroKernelException;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.spi.commit.ChangeDispatcher;
-import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -33,12 +30,6 @@ import org.apache.jackrabbit.oak.spi.sta
public class MongoNodeStoreBranch
extends AbstractNodeStoreBranch<MongoNodeStore, MongoNodeState> {
- /**
- * TODO: what is a reasonable value?
- * TODO: fall back to pessimistic approach? how does this work in a
cluster?
- */
- private static final int MERGE_RETRIES = 10;
-
public MongoNodeStoreBranch(MongoNodeStore store,
MongoNodeState base) {
super(store, new ChangeDispatcher(store.getRoot()), base);
@@ -61,10 +52,19 @@ public class MongoNodeStoreBranch
}
@Override
- protected MongoNodeState merge(MongoNodeState branchHead, CommitInfo info)
{
+ protected MongoNodeState merge(MongoNodeState branchHead, CommitInfo info)
+ throws CommitFailedException {
return store.getRoot(store.merge(branchHead.getRevision(), info));
}
+ @Nonnull
+ @Override
+ protected MongoNodeState reset(@Nonnull MongoNodeState branchHead,
+ @Nonnull MongoNodeState ancestor) {
+ return store.getRoot(store.reset(branchHead.getRevision(),
+ ancestor.getRevision())).setBranch();
+ }
+
@Override
protected MongoNodeState persist(final NodeState toPersist,
final MongoNodeState base,
@@ -106,25 +106,6 @@ public class MongoNodeStoreBranch
}, base, null);
}
- //--------------------< AbstractNodeStoreBranch
>---------------------------
-
- @Nonnull
- @Override
- public NodeState merge(@Nonnull CommitHook hook, @Nullable CommitInfo info)
- throws CommitFailedException {
- MicroKernelException ex = null;
- for (int i = 0; i < MERGE_RETRIES; i++) {
- try {
- return super.merge(hook, info);
- } catch (MicroKernelException e) {
- ex = e;
- }
- }
- throw new CommitFailedException(
- "Kernel", 1,
- "Failed to merge changes to the underlying store", ex);
- }
-
//------------------------------< internal
>--------------------------------
/**
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
Mon Nov 25 09:43:55 2013
@@ -843,9 +843,9 @@ public class NodeDocument extends Docume
checkNotNull(op).unsetMapEntry(REVISIONS, checkNotNull(revision));
}
- public static void unsetCollision(@Nonnull UpdateOp op,
- @Nonnull Revision revision) {
- checkNotNull(op).unsetMapEntry(COLLISIONS, checkNotNull(revision));
+ public static void removeCollision(@Nonnull UpdateOp op,
+ @Nonnull Revision revision) {
+ checkNotNull(op).removeMapEntry(COLLISIONS, checkNotNull(revision));
}
public static void setLastRev(@Nonnull UpdateOp op,
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java
Mon Nov 25 09:43:55 2013
@@ -21,6 +21,8 @@ import java.util.Random;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.MERGE;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.OAK;
import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
@@ -105,8 +107,22 @@ public abstract class AbstractNodeStoreB
* @param branchHead the head of the branch to merge.
* @param info the commit info or <code>null</code> if none available.
* @return the result state of the merge.
+ * @throws CommitFailedException if the merge fails. The type of the
+ * exception will be {@code
CommitFailedException.MERGE}.
*/
- protected abstract N merge(N branchHead, CommitInfo info);
+ protected abstract N merge(N branchHead, CommitInfo info)
+ throws CommitFailedException;
+
+ /**
+ * Resets the branch head to the given ancestor on the same branch.
+ *
+ * @param branchHead the head of the branch to reset.
+ * @param ancestor the state of the branch to reset to.
+ * @return the state of the reset branch. This is not necessarily the same
+ * instance as {@code ancestor} but is guaranteed to be equal to
it.
+ */
+ @Nonnull
+ protected abstract N reset(@Nonnull N branchHead, @Nonnull N ancestor);
/**
* Persists the changes between <code>toPersist</code> and
<code>base</code>
@@ -231,7 +247,30 @@ public abstract class AbstractNodeStoreB
@Override
public NodeState merge(@Nonnull CommitHook hook, @Nullable CommitInfo info)
throws CommitFailedException {
- return branchState.merge(checkNotNull(hook), info);
+ CommitFailedException ex = null;
+ for (long backoff = 100; backoff < maximumBackoff; backoff *= 2) {
+ if (ex != null) {
+ try {
+ Thread.sleep(backoff, RANDOM.nextInt(1000000));
+ } catch (InterruptedException ie) {
+ // ignore
+ Thread.interrupted();
+ }
+ }
+ try {
+ return branchState.merge(checkNotNull(hook), info);
+ } catch (CommitFailedException e) {
+ ex = e;
+ // only retry on merge failures. these may be caused by
+ // changes introduce by a commit hook and may be resolved
+ // by a rebase and running the hook again
+ if (!e.isOfType(MERGE)) {
+ throw e;
+ }
+ }
+ }
+ // if we get here retrying failed
+ throw ex;
}
@Override
@@ -294,7 +333,10 @@ public abstract class AbstractNodeStoreB
* @param hook the commit hook to run.
* @param info the associated commit info.
* @return the result of the merge.
- * @throws CommitFailedException if a commit hook rejected the changes.
+ * @throws CommitFailedException if a commit hook rejected the changes
+ * or the actual merge operation failed. An implementation
must
+ * use the appropriate type in {@code CommitFailedException}
to
+ * indicate the cause of the exception.
*/
@Nonnull
abstract NodeState merge(@Nonnull CommitHook hook, @Nullable
CommitInfo info)
@@ -403,31 +445,18 @@ public abstract class AbstractNodeStoreB
NodeState merge(@Nonnull CommitHook hook, CommitInfo info)
throws CommitFailedException {
try {
- CommitFailedException ex = null;
- for (long backoff = 100; backoff < maximumBackoff; backoff *=
2) {
- if (ex != null) {
- try {
- Thread.sleep(backoff, RANDOM.nextInt(1000000));
- } catch (InterruptedException ie) {
- // ignore
- Thread.interrupted();
- }
- }
- rebase();
- dispatcher.contentChanged(base, null);
- NodeState toCommit =
checkNotNull(hook).processCommit(base, head);
- try {
- NodeState newHead =
AbstractNodeStoreBranch.this.persist(toCommit, base, info);
- dispatcher.contentChanged(newHead, info);
- branchState = new Merged(base);
- return newHead;
- } catch (Exception e) {
- ex = new CommitFailedException(
- "Kernel", 1,
- "Failed to merge changes to the underlying
store", e);
- }
+ rebase();
+ dispatcher.contentChanged(base, null);
+ NodeState toCommit = checkNotNull(hook).processCommit(base,
head);
+ try {
+ NodeState newHead =
AbstractNodeStoreBranch.this.persist(toCommit, base, info);
+ dispatcher.contentChanged(newHead, info);
+ branchState = new Merged(base);
+ return newHead;
+ } catch (Exception e) {
+ throw new CommitFailedException(MERGE, 1,
+ "Failed to merge changes to the underlying store",
e);
}
- throw ex;
} finally {
dispatcher.contentChanged(getRoot(), null);
}
@@ -442,7 +471,8 @@ public abstract class AbstractNodeStoreB
* <ul>
* <li>{@link Unmodified} on {@link #setRoot(NodeState)} if the new
root is the same
* as the base of this branch.
- * <li>{@link Merged} on {@link #merge(CommitHook, CommitInfo)}</li>
+ * <li>{@link ResetFailed} on failed reset in {@link
#merge(CommitHook, CommitInfo)}</li>
+ * <li>{@link Merged} on successful {@link #merge(CommitHook,
CommitInfo)}</li>
* </ul>
*/
private class Persisted extends BranchState {
@@ -499,21 +529,31 @@ public abstract class AbstractNodeStoreB
@Override
@Nonnull
- NodeState merge(@Nonnull CommitHook hook, CommitInfo info) throws
CommitFailedException {
+ NodeState merge(@Nonnull CommitHook hook, CommitInfo info)
+ throws CommitFailedException {
try {
rebase();
dispatcher.contentChanged(base, null);
NodeState toCommit = checkNotNull(hook).processCommit(base,
head);
- if (toCommit.equals(base)) {
- branchState = new Merged(base);
- return base;
- } else {
- head = AbstractNodeStoreBranch.this.persist(toCommit,
head, info);
- NodeState newRoot =
AbstractNodeStoreBranch.this.merge(head, info);
- dispatcher.contentChanged(newRoot, info);
- branchState = new Merged(base);
- return newRoot;
+ N newRoot = AbstractNodeStoreBranch.this.persist(toCommit,
head, info);
+ boolean success = false;
+ try {
+ newRoot = AbstractNodeStoreBranch.this.merge(newRoot,
info);
+ success = true;
+ } finally {
+ if (!success) {
+ try {
+ AbstractNodeStoreBranch.this.reset(newRoot, head);
+ } catch (Exception e) {
+ CommitFailedException ex = new
CommitFailedException(
+ OAK, 100, "Branch reset failed",
e);
+ branchState = new ResetFailed(base, ex);
+ }
+ }
}
+ branchState = new Merged(base);
+ dispatcher.contentChanged(newRoot, info);
+ return newRoot;
} finally {
dispatcher.contentChanged(getRoot(), null);
}
@@ -563,4 +603,52 @@ public abstract class AbstractNodeStoreB
}
}
+ /**
+ * Instances of this class represent a branch with persisted changes and
+ * a failed attempt to reset changes.
+ * <p>
+ * Transitions to: none.
+ */
+ private class ResetFailed extends BranchState {
+
+ /**
+ * The exception of the failed reset.
+ */
+ private final CommitFailedException ex;
+
+ protected ResetFailed(N base, CommitFailedException e) {
+ super(base);
+ this.ex = e;
+ }
+
+ @Nonnull
+ @Override
+ NodeState getHead() {
+ throw new IllegalStateException("Branch with failed reset");
+ }
+
+ @Override
+ void setRoot(NodeState root) {
+ throw new IllegalStateException("Branch with failed reset");
+ }
+
+ @Override
+ void rebase() {
+ throw new IllegalStateException("Branch with failed reset");
+ }
+
+ /**
+ * Always throws the {@code CommitFailedException} passed to the
+ * constructor of this branch state.
+ *
+ * @throws CommitFailedException the exception of the failed reset.
+ */
+ @Nonnull
+ @Override
+ NodeState merge(@Nonnull CommitHook hook, @Nullable CommitInfo info)
+ throws CommitFailedException {
+ throw ex;
+ }
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MergeRetryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MergeRetryTest.java?rev=1545190&r1=1545189&r2=1545190&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MergeRetryTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MergeRetryTest.java
Mon Nov 25 09:43:55 2013
@@ -91,7 +91,6 @@ public class MergeRetryTest {
/**
* Test for OAK-1202
*/
- @Ignore
@Test
public void retryPersisted() throws Exception {
MemoryDocumentStore ds = new MemoryDocumentStore();