X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatabroker%2Factors%2Fdds%2FAbstractClientHistory.java;fp=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatabroker%2Factors%2Fdds%2FAbstractClientHistory.java;h=f364994e3deb40fd8ee41f2c87a88363840bb173;hp=0000000000000000000000000000000000000000;hb=98d1c5606bad9633ce5549bcd691a98c75abdf6a;hpb=e6b9c7e282a526aeb1469b6f7aa9b61f69d01743 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractClientHistory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractClientHistory.java new file mode 100644 index 0000000000..f364994e3d --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractClientHistory.java @@ -0,0 +1,93 @@ +/* + * 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.actors.dds; + +import com.google.common.base.Preconditions; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract base class for client view of a history. This class has two implementations, one for normal local histories + * and the other for single transactions. + * + * @author Robert Varga + */ +abstract class AbstractClientHistory extends LocalAbortable implements Identifiable { + static enum State { + IDLE, + TX_OPEN, + CLOSED, + } + + private static final Logger LOG = LoggerFactory.getLogger(AbstractClientHistory.class); + private static final AtomicReferenceFieldUpdater STATE_UPDATER = + AtomicReferenceFieldUpdater.newUpdater(AbstractClientHistory.class, State.class, "state"); + + private final Map histories = new ConcurrentHashMap<>(); + private final DistributedDataStoreClientBehavior client; + private final LocalHistoryIdentifier identifier; + + private volatile State state = State.IDLE; + + AbstractClientHistory(final DistributedDataStoreClientBehavior client, final LocalHistoryIdentifier identifier) { + this.client = Preconditions.checkNotNull(client); + this.identifier = Preconditions.checkNotNull(identifier); + Preconditions.checkArgument(identifier.getCookie() == 0); + } + + final State state() { + return state; + } + + final void updateState(final State expected, final State next) { + final boolean success = STATE_UPDATER.compareAndSet(this, expected, next); + Preconditions.checkState(success, "Race condition detected, state changed from %s to %s", expected, state); + } + + final LocalHistoryIdentifier getHistoryForCookie(final Long cookie) { + LocalHistoryIdentifier ret = histories.get(cookie); + if (ret == null) { + ret = new LocalHistoryIdentifier(identifier.getClientId(), identifier.getHistoryId(), cookie); + final LocalHistoryIdentifier existing = histories.putIfAbsent(cookie, ret); + if (existing != null) { + ret = existing; + } + } + + return ret; + } + + @Override + public final LocalHistoryIdentifier getIdentifier() { + return identifier; + } + + final DistributedDataStoreClientBehavior getClient() { + return client; + } + + @Override + final void localAbort(final Throwable cause) { + LOG.debug("Force-closing history {}", getIdentifier(), cause); + state = State.CLOSED; + } + + /** + * Callback invoked from {@link ClientTransaction} when a transaction has been sub + * + * @param transaction Transaction handle + */ + void onTransactionReady(final ClientTransaction transaction) { + client.transactionComplete(transaction); + } +}