*/
package org.opendaylight.controller.cluster.datastore;
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.cluster.access.commands.DeadTransactionException;
-import org.opendaylight.controller.cluster.access.commands.LocalHistorySuccess;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.primitives.UnsignedLong;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.SortedSet;
import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
-import org.opendaylight.controller.cluster.access.concepts.RequestEnvelope;
-import org.opendaylight.controller.cluster.access.concepts.RequestException;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.utils.MutableUnsignedLongSet;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* Chained transaction specialization of {@link AbstractFrontendHistory}. It prevents concurrent open transactions.
* @author Robert Varga
*/
final class LocalFrontendHistory extends AbstractFrontendHistory {
- private static final Logger LOG = LoggerFactory.getLogger(LocalFrontendHistory.class);
-
private final ShardDataTreeTransactionChain chain;
- private final ShardDataTree tree;
- private Long lastSeenTransaction;
+ private LocalFrontendHistory(final String persistenceId, final ShardDataTree tree,
+ final ShardDataTreeTransactionChain chain, final Map<UnsignedLong, Boolean> closedTransactions,
+ final MutableUnsignedLongSet purgedTransactions) {
+ super(persistenceId, tree, closedTransactions, purgedTransactions);
+ this.chain = requireNonNull(chain);
+ }
- LocalFrontendHistory(final String persistenceId, final ShardDataTree tree,
+ static LocalFrontendHistory create(final String persistenceId, final ShardDataTree tree,
final ShardDataTreeTransactionChain chain) {
- super(persistenceId, tree.ticker());
- this.tree = Preconditions.checkNotNull(tree);
- this.chain = Preconditions.checkNotNull(chain);
+ return new LocalFrontendHistory(persistenceId, tree, chain, ImmutableMap.of(), MutableUnsignedLongSet.of());
+ }
+
+ static LocalFrontendHistory recreate(final String persistenceId, final ShardDataTree tree,
+ final ShardDataTreeTransactionChain chain, final Map<UnsignedLong, Boolean> closedTransactions,
+ final MutableUnsignedLongSet purgedTransactions) {
+ return new LocalFrontendHistory(persistenceId, tree, chain, new HashMap<>(closedTransactions),
+ purgedTransactions.mutableCopy());
}
@Override
}
@Override
- FrontendTransaction createOpenSnapshot(final TransactionIdentifier id) throws RequestException {
- checkDeadTransaction(id);
- lastSeenTransaction = id.getTransactionId();
+ FrontendTransaction createOpenSnapshot(final TransactionIdentifier id) {
return FrontendReadOnlyTransaction.create(this, chain.newReadOnlyTransaction(id));
}
@Override
- FrontendTransaction createOpenTransaction(final TransactionIdentifier id) throws RequestException {
- checkDeadTransaction(id);
- lastSeenTransaction = id.getTransactionId();
+ FrontendTransaction createOpenTransaction(final TransactionIdentifier id) {
return FrontendReadWriteTransaction.createOpen(this, chain.newReadWriteTransaction(id));
}
@Override
- FrontendTransaction createReadyTransaction(final TransactionIdentifier id, final DataTreeModification mod)
- throws RequestException {
- checkDeadTransaction(id);
- lastSeenTransaction = id.getTransactionId();
+ FrontendTransaction createReadyTransaction(final TransactionIdentifier id, final DataTreeModification mod) {
return FrontendReadWriteTransaction.createReady(this, id, mod);
}
@Override
- ShardDataTreeCohort createReadyCohort(final TransactionIdentifier id, final DataTreeModification mod) {
- return chain.createReadyCohort(id, mod);
+ ShardDataTreeCohort createFailedCohort(final TransactionIdentifier id, final DataTreeModification mod,
+ final Exception failure) {
+ return chain.createFailedCohort(id, mod, failure);
}
- void destroy(final long sequence, final RequestEnvelope envelope, final long now)
- throws RequestException {
- LOG.debug("{}: closing history {}", persistenceId(), getIdentifier());
- tree.closeTransactionChain(getIdentifier(), () -> {
- envelope.sendSuccess(new LocalHistorySuccess(getIdentifier(), sequence), readTime() - now);
- });
- }
-
- void purge(final long sequence, final RequestEnvelope envelope, final long now) {
- LOG.debug("{}: purging history {}", persistenceId(), getIdentifier());
- tree.purgeTransactionChain(getIdentifier(), () -> {
- envelope.sendSuccess(new LocalHistorySuccess(getIdentifier(), sequence), readTime() - now);
- });
- }
-
- private void checkDeadTransaction(final TransactionIdentifier id) throws RequestException {
- // FIXME: check if this history is still open
- // FIXME: check if the last transaction has been submitted
-
- // Transaction identifiers within a local history have to have increasing IDs
- if (lastSeenTransaction != null && Long.compareUnsigned(lastSeenTransaction, id.getTransactionId()) >= 0) {
- throw new DeadTransactionException(lastSeenTransaction);
- }
+ @Override
+ ShardDataTreeCohort createReadyCohort(final TransactionIdentifier id, final DataTreeModification mod,
+ final Optional<SortedSet<String>> participatingShardNames) {
+ return chain.createReadyCohort(id, mod, participatingShardNames);
}
}