Author: mreutegg
Date: Wed Jul  4 15:27:24 2018
New Revision: 1835062

URL: http://svn.apache.org/viewvc?rev=1835062&view=rev
Log:
OAK-7564: Commit fails when forced journal push throws exception

Modified:
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java?rev=1835062&r1=1835061&r2=1835062&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
 Wed Jul  4 15:27:24 2018
@@ -715,6 +715,25 @@ public class Commit {
     }
 
     /**
+     * Applies the lastRev updates to the {@link LastRevTracker} of the
+     * DocumentNodeStore.
+     *
+     * @param isBranchCommit whether this is a branch commit.
+     */
+    void applyLastRevUpdates(boolean isBranchCommit) {
+        LastRevTracker tracker = nodeStore.createTracker(revision, 
isBranchCommit);
+        for (String path : modifiedNodes) {
+            UpdateOp op = operations.get(path);
+            // track _lastRev only when path is not for a bundled node state
+            if ((op == null || !hasContentChanges(op) || denotesRoot(path))
+                    && !isBundled(path)) {
+                // track intermediate node and root
+                tracker.track(path);
+            }
+        }
+    }
+
+    /**
      * Apply the changes to the DocumentNodeStore (to update the cache).
      *
      * @param before the revision right before this commit.
@@ -738,7 +757,6 @@ public class Commit {
         Revision rev = isBranchCommit ? revision.asBranchRevision() : revision;
         RevisionVector after = before.update(rev);
         DiffCache.Entry cacheEntry = nodeStore.getDiffCache().newEntry(before, 
after, true);
-        LastRevTracker tracker = nodeStore.createTracker(revision, 
isBranchCommit);
         List<String> added = new ArrayList<String>();
         List<String> removed = new ArrayList<String>();
         List<String> changed = new ArrayList<String>();
@@ -760,14 +778,9 @@ public class Commit {
             }
             UpdateOp op = operations.get(path);
 
-            // track _lastRev and apply to cache only when
-            // path is not for a bundled node state
+            // apply to cache only when path is not for a bundled node state
             if (!isBundled(path)) {
                 boolean isNew = op != null && op.isNew();
-                if (op == null || !hasContentChanges(op) || denotesRoot(path)) 
{
-                    // track intermediate node and root
-                    tracker.track(path);
-                }
                 nodeStore.applyChanges(before, after, rev, path, isNew,
                         added, removed, changed);
             }

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1835062&r1=1835061&r2=1835062&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 Wed Jul  4 15:27:24 2018
@@ -876,23 +876,50 @@ public final class DocumentNodeStore
                     public void headOfQueue(@Nonnull Revision revision) {
                         // remember before revision
                         RevisionVector before = getHeadRevision();
-                        // apply changes to cache based on before revision
-                        c.applyToCache(before, false);
-                        // track modified paths
-                        changes.modified(c.getModifiedPaths());
-                        changes.readFrom(info);
-                        changes.addChangeSet(getChangeSet(info));
+
                         // update head revision
                         Revision r = c.getRevision();
                         newHead[0] = before.update(r);
-                        if (changes.getNumChangedNodes() >= 
journalPushThreshold) {
-                            LOG.info("Pushing journal entry at {} as number of 
changes ({}) have reached {}",
-                                    r, changes.getNumChangedNodes(), 
journalPushThreshold);
-                            pushJournalEntry(r);
+                        boolean success = false;
+                        boolean cacheUpdated = false;
+                        try {
+                            // apply lastRev updates
+                            c.applyLastRevUpdates(false);
+
+                            // track modified paths
+                            changes.modified(c.getModifiedPaths());
+                            changes.readFrom(info);
+                            changes.addChangeSet(getChangeSet(info));
+
+                            // if we get here all required in-memory changes
+                            // have been applied. The following operations in
+                            // the try block may fail and the commit can still
+                            // be considered successful
+                            success = true;
+
+                            // apply changes to cache, based on before revision
+                            c.applyToCache(before, false);
+                            cacheUpdated = true;
+                            if (changes.getNumChangedNodes() >= 
journalPushThreshold) {
+                                LOG.info("Pushing journal entry at {} as 
number of changes ({}) have reached threshold of {}",
+                                        r, changes.getNumChangedNodes(), 
journalPushThreshold);
+                                pushJournalEntry(r);
+                            }
+                        } catch (Throwable e) {
+                            if (success) {
+                                if (cacheUpdated) {
+                                    LOG.warn("Pushing journal entry at {} 
failed", revision, e);
+                                } else {
+                                    LOG.warn("Updating caches at {} failed", 
revision, e);
+                                }
+                            } else {
+                                LOG.error("Applying in-memory changes at {} 
failed", revision, e);
+                            }
+                        } finally {
+                            setRoot(newHead[0]);
+                            commitQueue.headRevisionChanged();
+                            dispatcher.contentChanged(getRoot(), info);
                         }
-                        setRoot(newHead[0]);
-                        commitQueue.headRevisionChanged();
-                        dispatcher.contentChanged(getRoot(), info);
                     }
                 });
                 return newHead[0];
@@ -902,6 +929,7 @@ public final class DocumentNodeStore
         } else {
             // branch commit
             try {
+                c.applyLastRevUpdates(isBranch);
                 c.applyToCache(c.getBaseRevision(), isBranch);
                 return 
c.getBaseRevision().update(c.getRevision().asBranchRevision());
             } finally {
@@ -2501,7 +2529,7 @@ public final class DocumentNodeStore
         }
     }
 
-    private void pushJournalEntry(Revision r) {
+    private void pushJournalEntry(Revision r) throws DocumentStoreException {
         if (!changes.hasChanges()) {
             LOG.debug("Not pushing journal as there are no changes");
         } else if (store.create(JOURNAL, 
singletonList(changes.asUpdateOp(r)))) {

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java?rev=1835062&r1=1835061&r2=1835062&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java
 Wed Jul  4 15:27:24 2018
@@ -52,9 +52,14 @@ class MergeCommit extends Commit {
     }
 
     @Override
-    public void applyToCache(RevisionVector before, boolean isBranchCommit) {
+    void applyLastRevUpdates(boolean isBranchCommit) {
         // do nothing for a merge commit, only notify node
         // store about merged revisions
         nodeStore.revisionsMerged(branchCommits);
     }
+
+    @Override
+    public void applyToCache(RevisionVector before, boolean isBranchCommit) {
+        // do nothing for a merge commit
+    }
 }

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1835062&r1=1835061&r2=1835062&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
 Wed Jul  4 15:27:24 2018
@@ -2910,7 +2910,6 @@ public class DocumentNodeStoreTest {
     }
 
     // OAK-7564
-    @Ignore("OAK-7564")
     @Test
     public void forceJournalFlushWithException() throws Exception {
         AtomicBoolean failJournalOps = new AtomicBoolean();


Reply via email to