2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.databroker;
10 import static java.util.Objects.requireNonNull;
12 import java.lang.ref.Cleaner;
13 import java.lang.ref.Cleaner.Cleanable;
14 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
15 import org.opendaylight.controller.cluster.databroker.actors.dds.AbstractClientHandle;
16 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientTransaction;
17 import org.opendaylight.mdsal.dom.spi.store.AbstractDOMStoreTransaction;
18 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransaction;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
23 * An implementation of {@link DOMStoreTransaction} backed by a {@link ClientTransaction}. It guards against user-level
24 * leaks by maintaining a phantom reference on the backing transaction, which will ensure that the transaction will
25 * be aborted, if it is not otherwise closed, just before this object is garbage-collected.
27 * @author Robert Varga
29 abstract class ClientBackedTransaction<T extends AbstractClientHandle<?>> extends
30 AbstractDOMStoreTransaction<TransactionIdentifier> {
31 private static final class Cleanup implements Runnable {
32 private final AbstractClientHandle<?> transaction;
33 private final Throwable allocationContext;
35 Cleanup(final AbstractClientHandle<?> transaction, final Throwable allocationContext) {
36 this.transaction = transaction;
37 this.allocationContext = allocationContext;
42 if (transaction.abort()) {
43 LOG.info("Aborted orphan transaction {}", transaction, allocationContext);
48 private static final Logger LOG = LoggerFactory.getLogger(ClientBackedTransaction.class);
49 private static final Cleaner CLEANER = Cleaner.create();
51 private final T delegate;
52 private final Cleanable cleanable;
54 ClientBackedTransaction(final T delegate, final Throwable allocationContext) {
55 super(delegate.getIdentifier());
56 this.delegate = requireNonNull(delegate);
57 this.cleanable = CLEANER.register(this, new Cleanup(delegate, allocationContext));
63 // Run cleaning immediate so the references is not stuck in cleaner queue