From: Robert Varga Date: Thu, 12 Apr 2018 11:11:38 +0000 (+0200) Subject: Release permits as transactions are replayed X-Git-Tag: release/fluorine~118 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=57775303636cc55b83430eb2eef3fa589129e8b6;ds=sidebyside Release permits as transactions are replayed Since we have correct accounting at the cost of needing to finish the transition to new context in user thread, we need to make sure we release permits as we push them towards the TransactionContext if it is not handling it itself -- hence the user threads will not be charged for operations which have logically been completed. CONTROLLER-1825 Change-Id: I4bae984b08b99a042766d0a41475110781ef8377 Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionContextWrapper.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionContextWrapper.java index 0e1260962d..d11ee3e0bd 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionContextWrapper.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionContextWrapper.java @@ -166,9 +166,6 @@ class TransactionContextWrapper { if (!pendingEnqueue) { // We're done invoking the TransactionOperations so we can now publish the TransactionContext. localTransactionContext.operationHandOffComplete(); - if (!localTransactionContext.usesOperationLimiting()) { - limiter.releaseAll(); - } // This is null-to-non-null transition after which we are releasing the lock and not doing // any further processing. @@ -183,11 +180,16 @@ class TransactionContextWrapper { queuedTxOperations.clear(); } - // Invoke TransactionOperations outside the sync block to avoid unnecessary blocking. - // A slight down-side is that we need to re-acquire the lock below but this should - // be negligible. + // Invoke TransactionOperations outside the sync block to avoid unnecessary blocking. A slight down-side is + // that we need to re-acquire the lock below but this should be negligible. for (Entry oper : operationsBatch) { - oper.getKey().invoke(localTransactionContext, oper.getValue()); + final Boolean permit = oper.getValue(); + if (permit.booleanValue() && !localTransactionContext.usesOperationLimiting()) { + // If the context is not using limiting we need to release operations as we are queueing them, so + // user threads are not charged for them. + limiter.release(); + } + oper.getKey().invoke(localTransactionContext, permit); } } }