From e3abb5765cd5a3dba4616b875b6026f1efc460e9 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 25 Apr 2017 12:55:44 +0200 Subject: [PATCH] Add ClientBackedTransaction allocation recording 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 (cherry picked from commit 52c35c0e63343d0009a689c970cafed5d005e337) --- .../databroker/ClientBackedDataStore.java | 16 ++++++++++++---- .../databroker/ClientBackedReadTransaction.java | 5 +++-- .../ClientBackedReadWriteTransaction.java | 5 +++-- .../databroker/ClientBackedTransaction.java | 17 +++++++++++------ .../ClientBackedTransactionChain.java | 14 ++++++++++---- .../ClientBackedWriteTransaction.java | 5 +++-- .../ClientBackedReadTransactionTest.java | 2 +- .../ClientBackedReadWriteTransactionTest.java | 2 +- .../ClientBackedTransactionChainTest.java | 2 +- .../ClientBackedWriteTransactionTest.java | 2 +- 10 files changed, 46 insertions(+), 24 deletions(-) diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedDataStore.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedDataStore.java index 940e5b2fbb..8aebe5bb19 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedDataStore.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedDataStore.java @@ -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; } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransaction.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransaction.java index 3d10c39760..3cbda25672 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransaction.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransaction.java @@ -33,8 +33,9 @@ final class ClientBackedReadTransaction extends ClientBackedTransaction> 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 recordTransaction( - @Nonnull final ClientBackedTransaction referent, @Nonnull final T transaction) { - FINALIZERS.add(new Finalizer(referent, transaction)); + @Nonnull final ClientBackedTransaction 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> 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() { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChain.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChain.java index db30372676..36d1b5d575 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChain.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChain.java @@ -35,24 +35,26 @@ final class ClientBackedTransactionChain implements DOMStoreTransactionChain { private final Map, 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 recordSnapshot(final T snapshot) { openSnapshots.put(snapshot, Boolean.TRUE); return snapshot; diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransaction.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransaction.java index 27a671d3c3..56ec344d81 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransaction.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransaction.java @@ -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 implements DOMStoreWriteTransaction { - ClientBackedWriteTransaction(final ClientTransaction delegate) { - super(delegate); + ClientBackedWriteTransaction(final ClientTransaction delegate, @Nullable final Throwable allocationContext) { + super(delegate, allocationContext); } @Override diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransactionTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransactionTest.java index ee8280f4e9..fcba12bdd7 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransactionTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadTransactionTest.java @@ -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 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadWriteTransactionTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadWriteTransactionTest.java index bb3b215ac2..db81e5b043 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadWriteTransactionTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedReadWriteTransactionTest.java @@ -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 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChainTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChainTest.java index dab278635f..2238bc4aeb 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChainTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChainTest.java @@ -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 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransactionTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransactionTest.java index 2f297b568c..8091f70553 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransactionTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ClientBackedWriteTransactionTest.java @@ -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 -- 2.36.6