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.actors.dds;
10 import com.google.common.base.Preconditions;
12 import java.util.concurrent.ConcurrentHashMap;
13 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
14 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
15 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
16 import org.opendaylight.yangtools.concepts.Identifiable;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
21 * Abstract base class for client view of a history. This class has two implementations, one for normal local histories
22 * and the other for single transactions.
24 * @author Robert Varga
26 abstract class AbstractClientHistory extends LocalAbortable implements Identifiable<LocalHistoryIdentifier> {
33 private static final Logger LOG = LoggerFactory.getLogger(AbstractClientHistory.class);
34 private static final AtomicReferenceFieldUpdater<AbstractClientHistory, State> STATE_UPDATER =
35 AtomicReferenceFieldUpdater.newUpdater(AbstractClientHistory.class, State.class, "state");
37 private final Map<Long, AbstractProxyHistory> histories = new ConcurrentHashMap<>();
38 private final DistributedDataStoreClientBehavior client;
39 private final LocalHistoryIdentifier identifier;
41 private volatile State state = State.IDLE;
43 AbstractClientHistory(final DistributedDataStoreClientBehavior client, final LocalHistoryIdentifier identifier) {
44 this.client = Preconditions.checkNotNull(client);
45 this.identifier = Preconditions.checkNotNull(identifier);
46 Preconditions.checkArgument(identifier.getCookie() == 0);
53 final void updateState(final State expected, final State next) {
54 final boolean success = STATE_UPDATER.compareAndSet(this, expected, next);
55 Preconditions.checkState(success, "Race condition detected, state changed from %s to %s", expected, state);
59 public final LocalHistoryIdentifier getIdentifier() {
63 final DistributedDataStoreClientBehavior getClient() {
68 final void localAbort(final Throwable cause) {
69 LOG.debug("Force-closing history {}", getIdentifier(), cause);
73 private AbstractProxyHistory createHistoryProxy(final Long shard) {
74 final LocalHistoryIdentifier historyId = new LocalHistoryIdentifier(identifier.getClientId(),
75 identifier.getHistoryId(), shard);
76 return AbstractProxyHistory.create(client, client.resolver().getFutureBackendInfo(shard), historyId);
79 final AbstractProxyTransaction createTransactionProxy(final TransactionIdentifier transactionId, final Long shard) {
80 final AbstractProxyHistory history = histories.computeIfAbsent(shard, this::createHistoryProxy);
81 return history.createTransactionProxy(transactionId);
85 * Callback invoked from {@link ClientTransaction} when a transaction has been sub
87 * @param transaction Transaction handle
89 void onTransactionReady(final ClientTransaction transaction) {
90 client.transactionComplete(transaction);