X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-dom-spi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fcore%2Fspi%2Fdata%2FSnapshotBackedReadTransaction.java;h=eaf3aa7913a5dd03f1f29684471311498b2c0c72;hp=8e5957c71a3f76e6f7a62ac146cce8bfbe4e6159;hb=a885056d2fddd17e3879aca9b75fe597e3be7953;hpb=3d460a8bcbc24eeb969319feb9c7bf16bff496c1;ds=sidebyside diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/SnapshotBackedReadTransaction.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/SnapshotBackedReadTransaction.java index 8e5957c71a..eaf3aa7913 100644 --- a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/SnapshotBackedReadTransaction.java +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/SnapshotBackedReadTransaction.java @@ -8,11 +8,13 @@ package org.opendaylight.controller.sal.core.spi.data; import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.annotations.Beta; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -21,17 +23,26 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** + * Implementation of read-only transaction backed by {@link DataTreeSnapshot}. * - * Implementation of read-only transaction backed by {@link DataTreeSnapshot} - * + *

* Implementation of read-only transaction backed by {@link DataTreeSnapshot} * which delegates most of its calls to similar methods provided by underlying snapshot. * - * identifier type + * @param identifier type */ @Beta -public final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements DOMStoreReadTransaction { +public final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction + implements DOMStoreReadTransaction { private static final Logger LOG = LoggerFactory.getLogger(SnapshotBackedReadTransaction.class); + + @SuppressWarnings("rawtypes") + private static final AtomicReferenceFieldUpdater SNAPSHOT_UPDATER = + AtomicReferenceFieldUpdater.newUpdater(SnapshotBackedReadTransaction.class, DataTreeSnapshot.class, + "stableSnapshot"); + + // Guarded by stableSnapshot CAS, hence it does not need to be volatile + private TransactionClosePrototype closeImpl; private volatile DataTreeSnapshot stableSnapshot; /** @@ -41,19 +52,31 @@ public final class SnapshotBackedReadTransaction extends AbstractDOMStoreTran * @param debug Enable transaction debugging * @param snapshot Snapshot which will be modified. */ - SnapshotBackedReadTransaction(final T identifier, final boolean debug, final DataTreeSnapshot snapshot) { + SnapshotBackedReadTransaction(final T identifier, final boolean debug, final DataTreeSnapshot snapshot, + final TransactionClosePrototype closeImpl) { super(identifier, debug); this.stableSnapshot = Preconditions.checkNotNull(snapshot); + this.closeImpl = closeImpl; LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot); } @Override public void close() { + final DataTreeSnapshot prev = SNAPSHOT_UPDATER.getAndSet(this, null); + if (prev == null) { + LOG.debug("Store transaction: {} : previously closed", getIdentifier()); + return; + } + LOG.debug("Store transaction: {} : Closed", getIdentifier()); - stableSnapshot = null; + if (closeImpl != null) { + closeImpl.transactionClosed(this); + closeImpl = null; + } } @Override + @SuppressWarnings("checkstyle:IllegalCatch") public CheckedFuture>, ReadFailedException> read(final YangInstanceIdentifier path) { LOG.debug("Tx: {} Read: {}", getIdentifier(), path); checkNotNull(path, "Path must not be null."); @@ -64,8 +87,8 @@ public final class SnapshotBackedReadTransaction extends AbstractDOMStoreTran } try { - return Futures.immediateCheckedFuture(snapshot.readNode(path)); - } catch (Exception e) { + return Futures.immediateCheckedFuture(Optional.fromJavaUtil(snapshot.readNode(path))); + } catch (RuntimeException e) { LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e); return Futures.immediateFailedCheckedFuture(new ReadFailedException("Read failed",e)); } @@ -82,4 +105,23 @@ public final class SnapshotBackedReadTransaction extends AbstractDOMStoreTran return Futures.immediateFailedCheckedFuture(e); } } + + /** + * Prototype implementation of {@link SnapshotBackedReadTransaction#close()}. + * + *

+ * This class is intended to be implemented by Transaction factories responsible for allocation + * of {@link org.opendaylight.mdsal.dom.spi.store.SnapshotBackedReadTransaction} and + * providing underlying logic for applying implementation. + * + * @param identifier type + */ + public interface TransactionClosePrototype { + /** + * Called when a transaction is closed. This is not invoked at most once for every transaction. + * + * @param tx Transaction which got closed. + */ + void transactionClosed(SnapshotBackedReadTransaction tx); + } }