All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.controller.cluster.databroker.ClientBackedTransaction Maven / Gradle / Ivy

There is a newer version: 10.0.5
Show newest version
/*
 * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.controller.cluster.databroker;

import static java.util.Objects.requireNonNull;

import java.lang.ref.Cleaner;
import java.lang.ref.Cleaner.Cleanable;
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;
import org.opendaylight.mdsal.dom.spi.store.AbstractDOMStoreTransaction;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An implementation of {@link DOMStoreTransaction} backed by a {@link ClientTransaction}. It guards against user-level
 * leaks by maintaining a phantom reference on the backing transaction, which will ensure that the transaction will
 * be aborted, if it is not otherwise closed, just before this object is garbage-collected.
 *
 * @author Robert Varga
 */
abstract class ClientBackedTransaction> extends
        AbstractDOMStoreTransaction {
    private static final class Cleanup implements Runnable {
        private final AbstractClientHandle transaction;
        private final Throwable allocationContext;

        Cleanup(final AbstractClientHandle transaction, final Throwable allocationContext) {
            this.transaction = transaction;
            this.allocationContext = allocationContext;
        }

        @Override
        public void run() {
            if (transaction.abort()) {
                LOG.info("Aborted orphan transaction {}", transaction, allocationContext);
            }
        }
    }

    private static final Logger LOG = LoggerFactory.getLogger(ClientBackedTransaction.class);
    private static final Cleaner CLEANER = Cleaner.create();

    private final T delegate;
    private final Cleanable cleanable;

    ClientBackedTransaction(final T delegate, final Throwable allocationContext) {
        super(delegate.getIdentifier());
        this.delegate = requireNonNull(delegate);
        this.cleanable = CLEANER.register(this, new Cleanup(delegate, allocationContext));
    }

    @Override
    public void close() {
        delegate.abort();
        // Run cleaning immediate so the references is not stuck in cleaner queue
        cleanable.clean();
    }

    final T delegate() {
        return delegate;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy