Add ClientBackedTransaction allocation recording 69/57369/2
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 25 Apr 2017 10:55:44 +0000 (12:55 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 18 May 2017 15:24:19 +0000 (15:24 +0000)
This patch adds a very simple recording of where a transaction
was allocated, aiding identification of callers who fail to close
transactions.

Change-Id: I9a8743c7a38e83c855102a3a25adecfea8599dfe
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 52c35c0e63343d0009a689c970cafed5d005e337)

opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedDataStore.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadWriteTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChain.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransactionTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadWriteTransactionTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChainTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransactionTest.java

index 940e5b2fbb162d9e5aa317a30b9edb48a07dfde6..8aebe5bb19337447dc7366d8fd86dc1eab2abf0f 100644 (file)
@@ -41,21 +41,29 @@ public class ClientBackedDataStore extends AbstractDataStore {
 
     @Override
     public DOMStoreTransactionChain createTransactionChain() {
-        return new ClientBackedTransactionChain(getClient().createLocalHistory());
+        return new ClientBackedTransactionChain(getClient().createLocalHistory(), debugAllocation());
     }
 
     @Override
     public DOMStoreReadTransaction newReadOnlyTransaction() {
-        return new ClientBackedReadTransaction(getClient().createSnapshot(), null);
+        return new ClientBackedReadTransaction(getClient().createSnapshot(), null, allocationContext());
     }
 
     @Override
     public DOMStoreWriteTransaction newWriteOnlyTransaction() {
-        return new ClientBackedWriteTransaction(getClient().createTransaction());
+        return new ClientBackedWriteTransaction(getClient().createTransaction(), allocationContext());
     }
 
     @Override
     public DOMStoreReadWriteTransaction newReadWriteTransaction() {
-        return new ClientBackedReadWriteTransaction(getClient().createTransaction());
+        return new ClientBackedReadWriteTransaction(getClient().createTransaction(), allocationContext());
+    }
+
+    private boolean debugAllocation() {
+        return getActorContext().getDatastoreContext().isTransactionDebugContextEnabled();
+    }
+
+    private Throwable allocationContext() {
+        return debugAllocation() ? new Throwable("allocated at") : null;
     }
 }
index 3d10c3976069da637cc9935a16a6828831d4c7e3..3cbda256729be7ac0d2b47748228cc095b95a206 100644 (file)
@@ -33,8 +33,9 @@ final class ClientBackedReadTransaction extends ClientBackedTransaction<ClientSn
     @SuppressWarnings("unused")
     private volatile ClientBackedTransactionChain parent;
 
-    ClientBackedReadTransaction(final ClientSnapshot delegate, @Nullable final ClientBackedTransactionChain parent) {
-        super(delegate);
+    ClientBackedReadTransaction(final ClientSnapshot delegate, @Nullable final ClientBackedTransactionChain parent,
+        @Nullable final Throwable allocationContext) {
+        super(delegate, allocationContext);
         this.parent = parent;
     }
 
index a1bbe6189569373040ed0fd4c75c2be93e206041..9a73fc8dcc701dd3be62304a64f6ac1997705394 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.cluster.databroker;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
+import javax.annotation.Nullable;
 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
@@ -24,8 +25,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 final class ClientBackedReadWriteTransaction extends ClientBackedWriteTransaction
         implements DOMStoreReadWriteTransaction {
 
-    ClientBackedReadWriteTransaction(final ClientTransaction delegate) {
-        super(delegate);
+    ClientBackedReadWriteTransaction(final ClientTransaction delegate, @Nullable final Throwable allocationContext) {
+        super(delegate, allocationContext);
     }
 
     @Override
index a01f7a2d6a449a0fb1aef84d2f0deaecf5a7679f..5b6a451ca8e6f0b97444f8480dc011d33c77dec2 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.base.Preconditions;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
 import org.opendaylight.controller.cluster.databroker.actors.dds.AbstractClientHandle;
 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientTransaction;
@@ -35,15 +36,19 @@ abstract class ClientBackedTransaction<T extends AbstractClientHandle<?>> extend
         private static final Logger LOG = LoggerFactory.getLogger(Finalizer.class);
 
         private final AbstractClientHandle<?> transaction;
+        private final Throwable allocationContext;
 
-        private Finalizer(final ClientBackedTransaction<?> referent, final AbstractClientHandle<?> transaction) {
+        private Finalizer(final ClientBackedTransaction<?> referent, final AbstractClientHandle<?> transaction,
+                final Throwable allocationContext) {
             super(referent, QUEUE);
             this.transaction = Preconditions.checkNotNull(transaction);
+            this.allocationContext = allocationContext;
         }
 
         static @Nonnull <T extends AbstractClientHandle<?>> T recordTransaction(
-                @Nonnull final ClientBackedTransaction<T> referent, @Nonnull final T transaction) {
-            FINALIZERS.add(new Finalizer(referent, transaction));
+                @Nonnull final ClientBackedTransaction<T> referent, @Nonnull final T transaction,
+                @Nullable final Throwable allocationContext) {
+            FINALIZERS.add(new Finalizer(referent, transaction, allocationContext));
             return transaction;
         }
 
@@ -51,16 +56,16 @@ abstract class ClientBackedTransaction<T extends AbstractClientHandle<?>> extend
         public void finalizeReferent() {
             FINALIZERS.remove(this);
             if (transaction.abort()) {
-                LOG.info("Aborted orphan transaction {}", transaction);
+                LOG.info("Aborted orphan transaction {}", transaction, allocationContext);
             }
         }
     }
 
     private final T delegate;
 
-    ClientBackedTransaction(final T delegate) {
+    ClientBackedTransaction(final T delegate, final Throwable allocationContext) {
         super(delegate.getIdentifier());
-        this.delegate = Finalizer.recordTransaction(this, delegate);
+        this.delegate = Finalizer.recordTransaction(this, delegate, allocationContext);
     }
 
     final T delegate() {
index db30372676c43057749ae11d157901eaa77978d3..36d1b5d575a3c01353112465a2fc41c78d670434 100644 (file)
@@ -35,24 +35,26 @@ final class ClientBackedTransactionChain implements DOMStoreTransactionChain {
     private final Map<AbstractClientHandle<?>, Boolean> openSnapshots = new WeakHashMap<>();
 
     private final ClientLocalHistory history;
+    private final boolean debugAllocation;
 
-    ClientBackedTransactionChain(final ClientLocalHistory history) {
+    ClientBackedTransactionChain(final ClientLocalHistory history, final boolean debugAllocation) {
         this.history = Preconditions.checkNotNull(history);
+        this.debugAllocation = debugAllocation;
     }
 
     @Override
     public DOMStoreReadTransaction newReadOnlyTransaction() {
-        return new ClientBackedReadTransaction(createSnapshot(), this);
+        return new ClientBackedReadTransaction(createSnapshot(), this, allocationContext());
     }
 
     @Override
     public DOMStoreReadWriteTransaction newReadWriteTransaction() {
-        return new ClientBackedReadWriteTransaction(createTransaction());
+        return new ClientBackedReadWriteTransaction(createTransaction(), allocationContext());
     }
 
     @Override
     public DOMStoreWriteTransaction newWriteOnlyTransaction() {
-        return new ClientBackedWriteTransaction(createTransaction());
+        return new ClientBackedWriteTransaction(createTransaction(), allocationContext());
     }
 
     @Override
@@ -86,6 +88,10 @@ final class ClientBackedTransactionChain implements DOMStoreTransactionChain {
         }
     }
 
+    private Throwable allocationContext() {
+        return debugAllocation ? new Throwable("allocated at") : null;
+    }
+
     private synchronized <T extends AbstractClientHandle<?>> T recordSnapshot(final T snapshot) {
         openSnapshots.put(snapshot, Boolean.TRUE);
         return snapshot;
index 27a671d3c33e704a1a96008661576cf0d42f38c9..56ec344d81ecd68de6e599523164e01f70b376d2 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.cluster.databroker;
 
+import javax.annotation.Nullable;
 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
@@ -20,8 +21,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  */
 class ClientBackedWriteTransaction extends ClientBackedTransaction<ClientTransaction>
         implements DOMStoreWriteTransaction {
-    ClientBackedWriteTransaction(final ClientTransaction delegate) {
-        super(delegate);
+    ClientBackedWriteTransaction(final ClientTransaction delegate, @Nullable final Throwable allocationContext) {
+        super(delegate, allocationContext);
     }
 
     @Override
index ee8280f4e936b8c958266e149af7809bb48e9563..fcba12bdd7f3ef3ac9eae1dc9d9bff7699bb140e 100644 (file)
@@ -49,7 +49,7 @@ public class ClientBackedReadTransactionTest extends ClientBackedTransactionTest
         Mockito.doReturn(Futures.immediateCheckedFuture(Optional.of(data))).when(delegate)
                 .read(YangInstanceIdentifier.EMPTY);
 
-        object = new ClientBackedReadTransaction(delegate, null);
+        object = new ClientBackedReadTransaction(delegate, null, null);
     }
 
     @Test
index bb3b215ac2aec06726fd8ba938a8c53cb9a12527..db81e5b043ea6789d8ac1196a405420a432f2e3f 100644 (file)
@@ -50,7 +50,7 @@ public class ClientBackedReadWriteTransactionTest
         Mockito.doReturn(Futures.immediateCheckedFuture(Optional.of(data))).when(delegate)
                 .read(YangInstanceIdentifier.EMPTY);
 
-        object = new ClientBackedReadWriteTransaction(delegate);
+        object = new ClientBackedReadWriteTransaction(delegate, null);
     }
 
     @Test
index dab278635f837f479a93d02d1228e41bb3fa9a60..2238bc4aebc1ab9fe1cafab4a84aa39dfd13f1b9 100644 (file)
@@ -49,7 +49,7 @@ public class ClientBackedTransactionChainTest {
         Mockito.when(history.takeSnapshot()).thenReturn(snapshot);
         Mockito.when(history.createTransaction()).thenReturn(transaction);
 
-        chain = new ClientBackedTransactionChain(history);
+        chain = new ClientBackedTransactionChain(history, false);
     }
 
     @Test
index 2f297b568c118eaed9cc62020ae09620a48c574a..8091f705530ea86bb4e7f459a10354caa8ccf9a1 100644 (file)
@@ -37,7 +37,7 @@ public class ClientBackedWriteTransactionTest extends ClientBackedTransactionTes
         Mockito.doReturn(TRANSACTION_ID).when(delegate).getIdentifier();
         Mockito.doReturn(readyCohort).when(delegate).ready();
 
-        object = new ClientBackedWriteTransaction(delegate);
+        object = new ClientBackedWriteTransaction(delegate, null);
     }
 
     @Override