Author: mreutegg
Date: Tue Sep 22 15:30:08 2015
New Revision: 1704655

URL: http://svn.apache.org/viewvc?rev=1704655&view=rev
Log:
OAK-3433: Commit does not detect conflict when background read happens after 
rebase

Add yet another test, enable existing test and implement fix

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UnsavedModifications.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1704655&r1=1704654&r2=1704655&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 Tue Sep 22 15:30:08 2015
@@ -2084,9 +2084,9 @@ public final class DocumentNodeStore
     BackgroundWriteStats backgroundWrite() {
         return unsavedLastRevisions.persist(this, new 
UnsavedModifications.Snapshot() {
             @Override
-            public void acquiring() {
+            public void acquiring(Revision mostRecent) {
                 if (store.create(JOURNAL,
-                        singletonList(changes.asUpdateOp(getHeadRevision())))) 
{
+                        singletonList(changes.asUpdateOp(mostRecent)))) {
                     changes = JOURNAL.newDocument(getDocumentStore());
                 }
             }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java?rev=1704655&r1=1704654&r2=1704655&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
 Tue Sep 22 15:30:08 2015
@@ -235,7 +235,7 @@ public class LastRevRecoveryAgent {
             unsaved.persist(nodeStore, new UnsavedModifications.Snapshot() {
 
                 @Override
-                public void acquiring() {
+                public void acquiring(Revision mostRecent) {
                     if (lastRootRev == null) {
                         // this should never happen - when unsaved has no 
changes
                         // that is reflected in the 'map' to be empty - in that

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UnsavedModifications.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UnsavedModifications.java?rev=1704655&r1=1704654&r2=1704655&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UnsavedModifications.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UnsavedModifications.java
 Tue Sep 22 15:30:08 2015
@@ -159,7 +159,7 @@ class UnsavedModifications {
         time = clock.getTime();
         Map<String, Revision> pending;
         try {
-            snapshot.acquiring();
+            snapshot.acquiring(getMostRecentRevision());
             pending = Maps.newTreeMap(PathComparator.INSTANCE);
             pending.putAll(map);
         } finally {
@@ -234,14 +234,26 @@ class UnsavedModifications {
         return map.toString();
     }
 
+    private Revision getMostRecentRevision() {
+        // use revision of root document
+        Revision rev = map.get("/");
+        // otherwise find most recent
+        if (rev == null) {
+            for (Revision r : map.values()) {
+                rev = Utils.max(rev, r);
+            }
+        }
+        return rev;
+    }
+
     public interface Snapshot {
 
         Snapshot IGNORE = new Snapshot() {
             @Override
-            public void acquiring() {
+            public void acquiring(Revision mostRecent) {
             }
         };
 
-        void acquiring();
+        void acquiring(Revision mostRecent);
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalTest.java?rev=1704655&r1=1704654&r2=1704655&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalTest.java
 Tue Sep 22 15:30:08 2015
@@ -444,6 +444,31 @@ public class JournalTest extends Abstrac
         }
     }
 
+    // OAK-3433
+    @Test
+    public void journalEntryKey() throws Exception {
+        DocumentNodeStore ns1 = createMK(1, 0).getNodeStore();
+        DocumentNodeStore ns2 = createMK(2, 0).getNodeStore();
+
+        NodeBuilder b1 = ns1.getRoot().builder();
+        b1.child("foo");
+        ns1.merge(b1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        ns1.runBackgroundOperations();
+
+        NodeBuilder b2 = ns2.getRoot().builder();
+        b2.child("bar");
+        ns2.merge(b2, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        Revision h2 = ns2.getHeadRevision();
+
+        ns2.runBackgroundReadOperations();
+
+        ns2.runBackgroundOperations();
+
+        String id = JournalEntry.asId(h2);
+        assertTrue("Background update did not create a journal entry with id " 
+ id,
+                ns1.getDocumentStore().find(Collection.JOURNAL, id) != null);
+    }
+
     private DocumentMK createMK(int clusterId, int asyncDelay) {
         if (ds == null) {
             ds = new MemoryDocumentStore();

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java?rev=1704655&r1=1704654&r2=1704655&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/ClusterConflictTest.java
 Tue Sep 22 15:30:08 2015
@@ -32,10 +32,8 @@ import org.apache.jackrabbit.oak.spi.com
 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.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -61,7 +59,6 @@ public class ClusterConflictTest extends
     }
 
     // OAK-3433
-    @Ignore
     @Test
     public void mergeRetryWhileBackgroundRead() throws Exception {
         DocumentNodeStore ns1 = mk.getNodeStore();
@@ -100,7 +97,7 @@ public class ClusterConflictTest extends
         // because /a/b/c is seen as changed in the future
         // without the fix for OAK-3433:
         // the second merge attempt succeeds because now the
-        // /a/b/c change is visible and happened before the commit
+        // /a/b/c change revision is visible and happened before the commit
         // revision but before the base revision
         b2 = ns2.getRoot().builder();
         b2.child("z").setProperty("q", "v");
@@ -115,13 +112,18 @@ public class ClusterConflictTest extends
                     runBackgroundRead(ns2);
 
                     NodeBuilder builder = after.builder();
-                    builder.child("a").child("b").child("c").child("bar");
+                    if 
(builder.getChildNode("a").getChildNode("b").hasChildNode("c")) {
+                        builder.child("a").child("b").child("c").child("bar");
+                    } else {
+                        throw new CommitFailedException(
+                                CommitFailedException.OAK, 0,
+                                "/a/b/c does not exist anymore");
+                    }
                     return builder.getNodeState();
                 }
             }, CommitInfo.EMPTY);
             fail("Merge must fail with CommitFailedException");
         } catch (CommitFailedException e) {
-            e.printStackTrace();
             // expected
         }
     }


Reply via email to