Improve LocalProxyTransaction.doExists()
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / databroker / actors / dds / ClientLocalHistory.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.databroker.actors.dds;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import org.opendaylight.controller.cluster.access.client.AbstractClientConnection;
13 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
14 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
15
16 /**
17  * Client-side view of a local history. This class tracks all state related to a particular history and routes
18  * frontend requests towards the backend.
19  *
20  * <p>
21  * This interface is used by the world outside of the actor system and in the actor system it is manifested via
22  * its client actor. That requires some state transfer with {@link AbstractDataStoreClientBehavior}. In order to
23  * reduce request latency, all messages are carbon-copied (and enqueued first) to the client actor.
24  *
25  * @author Robert Varga
26  */
27 @Beta
28 public class ClientLocalHistory extends AbstractClientHistory implements AutoCloseable {
29     ClientLocalHistory(final AbstractDataStoreClientBehavior client, final LocalHistoryIdentifier historyId) {
30         super(client, historyId);
31     }
32
33     @Override
34     public void close() {
35         doClose();
36     }
37
38     private State ensureIdleState() {
39         final State local = state();
40         Preconditions.checkState(local == State.IDLE, "Local history %s state is %s", this, local);
41         return local;
42     }
43
44     @Override
45     ClientSnapshot doCreateSnapshot() {
46         ensureIdleState();
47         return new ClientSnapshot(this, new TransactionIdentifier(getIdentifier(), nextTx()));
48     }
49
50     @Override
51     ClientTransaction doCreateTransaction() {
52         updateState(ensureIdleState(), State.TX_OPEN);
53         return new ClientTransaction(this, new TransactionIdentifier(getIdentifier(), nextTx()));
54     }
55
56     @Override
57     void onTransactionAbort(final AbstractClientHandle<?> snap) {
58         if (snap instanceof ClientTransaction) {
59             final State local = state();
60             if (local == State.TX_OPEN) {
61                 updateState(local, State.IDLE);
62             }
63         }
64
65         super.onTransactionAbort(snap);
66     }
67
68     @Override
69     AbstractTransactionCommitCohort onTransactionReady(final ClientTransaction tx,
70             final AbstractTransactionCommitCohort cohort) {
71
72         final State local = state();
73         switch (local) {
74             case CLOSED:
75                 return super.onTransactionReady(tx, cohort);
76             case IDLE:
77                 throw new IllegalStateException(String.format("Local history %s is idle when readying transaction %s",
78                     this, tx.getIdentifier()));
79             case TX_OPEN:
80                 updateState(local, State.IDLE);
81                 return super.onTransactionReady(tx, cohort);
82             default:
83                 throw new IllegalStateException(String.format("Local history %s in unhandled state %s", this, local));
84
85         }
86     }
87
88     @Override
89     ProxyHistory createHistoryProxy(final LocalHistoryIdentifier historyId,
90             final AbstractClientConnection<ShardBackendInfo> connection) {
91         return ProxyHistory.createClient(this, connection, historyId);
92     }
93 }