Release permits as transactions are replayed 65/70965/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 12 Apr 2018 11:11:38 +0000 (13:11 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 18 Apr 2018 07:20:01 +0000 (07:20 +0000)
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 <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionContextWrapper.java

index 0e12609..d11ee3e 100644 (file)
@@ -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<TransactionOperation, Boolean> 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);
             }
         }
     }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.