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%2Fdatastore%2FTransactionChainProxy.java;h=4ef89b4684c907923274ee1fb4ef0ae6d554da27;hp=7c36adb70e6f65cdd559f68ff524b56461bc14ff;hb=f5f6ffd70f78e81106c04e1f1bb252e1e51a7617;hpb=576924996622ae1d4326363830001d529882a431 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxy.java index 7c36adb70e..4ef89b4684 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxy.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxy.java @@ -256,38 +256,42 @@ final class TransactionChainProxy extends AbstractTransactionContextFactory Future combineFutureWithPossiblePriorReadOnlyTxFutures(final Future future, final TransactionIdentifier txId) { - if (!priorReadOnlyTxPromises.containsKey(txId) && !priorReadOnlyTxPromises.isEmpty()) { - Collection>> priorReadOnlyTxPromiseEntries = - new ArrayList<>(priorReadOnlyTxPromises.entrySet()); - if (priorReadOnlyTxPromiseEntries.isEmpty()) { - return future; - } + return priorReadOnlyTxPromises.isEmpty() || priorReadOnlyTxPromises.containsKey(txId) ? future + // Tough luck, we need do some work + : combineWithPriorReadOnlyTxFutures(future, txId); + } - List> priorReadOnlyTxFutures = new ArrayList<>(priorReadOnlyTxPromiseEntries.size()); - for (Entry> entry: priorReadOnlyTxPromiseEntries) { - LOG.debug("Tx: {} - waiting on future for prior read-only Tx {}", txId, entry.getKey()); - priorReadOnlyTxFutures.add(entry.getValue().future()); - } + // Split out of the common path + private Future combineWithPriorReadOnlyTxFutures(final Future future, final TransactionIdentifier txId) { + // Take a stable snapshot, and check if we raced + final List>> priorReadOnlyTxPromiseEntries = + new ArrayList<>(priorReadOnlyTxPromises.entrySet()); + if (priorReadOnlyTxPromiseEntries.isEmpty()) { + return future; + } - Future> combinedFutures = Futures.sequence(priorReadOnlyTxFutures, - getActorUtils().getClientDispatcher()); + final List> priorReadOnlyTxFutures = new ArrayList<>(priorReadOnlyTxPromiseEntries.size()); + for (Entry> entry: priorReadOnlyTxPromiseEntries) { + LOG.debug("Tx: {} - waiting on future for prior read-only Tx {}", txId, entry.getKey()); + priorReadOnlyTxFutures.add(entry.getValue().future()); + } - final Promise returnPromise = Futures.promise(); - final OnComplete> onComplete = new OnComplete>() { - @Override - public void onComplete(final Throwable failure, final Iterable notUsed) { - LOG.debug("Tx: {} - prior read-only Tx futures complete", txId); + final Future> combinedFutures = Futures.sequence(priorReadOnlyTxFutures, + getActorUtils().getClientDispatcher()); - // Complete the returned Promise with the original Future. - returnPromise.completeWith(future); - } - }; + final Promise returnPromise = Futures.promise(); + final OnComplete> onComplete = new OnComplete<>() { + @Override + public void onComplete(final Throwable failure, final Iterable notUsed) { + LOG.debug("Tx: {} - prior read-only Tx futures complete", txId); - combinedFutures.onComplete(onComplete, getActorUtils().getClientDispatcher()); - return returnPromise.future(); - } else { - return future; - } + // Complete the returned Promise with the original Future. + returnPromise.completeWith(future); + } + }; + + combinedFutures.onComplete(onComplete, getActorUtils().getClientDispatcher()); + return returnPromise.future(); } @Override