BUG-8445: Guard against NPE 60/59160/2
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 19 Jun 2017 12:15:10 +0000 (14:15 +0200)
committerTom Pantelis <tompantelis@gmail.com>
Mon, 19 Jun 2017 20:31:56 +0000 (20:31 +0000)
We have observed this NPE:

[...]
Caused by: java.lang.NullPointerException
        at org.opendaylight.controller.cluster.datastore.ShardDataTree.startCanCommit(ShardDataTree.java:810)
        at org.opendaylight.controller.cluster.datastore.SimpleShardDataTreeCohort.canCommit(SimpleShardDataTreeCohort.java:105)
        at org.opendaylight.controller.cluster.datastore.ChainedCommitCohort.canCommit(ChainedCommitCohort.java:58)
        at org.opendaylight.controller.cluster.datastore.FrontendReadWriteTransaction.directCommit(FrontendReadWriteTransaction.java:384)
        at org.opendaylight.controller.cluster.datastore.FrontendReadWriteTransaction.handleModifyTransaction(FrontendReadWriteTransaction.java:527)
        at org.opendaylight.controller.cluster.datastore.FrontendReadWriteTransaction.doHandleRequest(FrontendReadWriteTransaction.java:174)
        at org.opendaylight.controller.cluster.datastore.FrontendTransaction.handleRequest(FrontendTransaction.java:141)

Which is quite weird, as the FrontendReadWriteTransaction state seems
to indicate the transaction is ready to be committed, yet ShardDataTree
does not seem to have a record of it.

While we are investigating the root cause, this patch adds an explicit
warning when this happens.

Change-Id: I2ddff76357c33d7df2b3f25a2703c69715fbd871
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardDataTree.java

index b32874c5fa5e17d87a53f704c2ad83df22b060e9..8b6df53a1ab1040a80eea43c6601f31d41db28b6 100644 (file)
@@ -807,8 +807,12 @@ public class ShardDataTree extends ShardDataTreeTransactionParent {
     }
 
     void startCanCommit(final SimpleShardDataTreeCohort cohort) {
-        final SimpleShardDataTreeCohort current = pendingTransactions.peek().cohort;
-        if (!cohort.equals(current)) {
+        final CommitEntry head = pendingTransactions.peek();
+        if (head == null) {
+            LOG.warn("{}: No transactions enqueued while attempting to start canCommit on {}", logContext, cohort);
+            return;
+        }
+        if (!cohort.equals(head.cohort)) {
             LOG.debug("{}: Transaction {} scheduled for canCommit step", logContext, cohort.getIdentifier());
             return;
         }