You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2021/06/08 16:00:10 UTC
[nifi] branch main updated: NIFI-8667: When marking a Controller
Service as enabled,
ensure that we release the write lock before calling validation methods of
referencing components. Otherwise, we can encounter a deadlock.
This is an automated email from the ASF dual-hosted git repository.
mattyb149 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 07ff4f2 NIFI-8667: When marking a Controller Service as enabled, ensure that we release the write lock before calling validation methods of referencing components. Otherwise, we can encounter a deadlock.
07ff4f2 is described below
commit 07ff4f2592b26a5b556bb1297c42325233bdb101
Author: Mark Payne <ma...@hotmail.com>
AuthorDate: Mon Jun 7 17:59:34 2021 -0400
NIFI-8667: When marking a Controller Service as enabled, ensure that we release the write lock before calling validation methods of referencing components. Otherwise, we can encounter a deadlock.
Signed-off-by: Matthew Burgess <ma...@apache.org>
This closes #5134
---
.../controller/service/ServiceStateTransition.java | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/ServiceStateTransition.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/ServiceStateTransition.java
index ae19388..afcfec4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/ServiceStateTransition.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/ServiceStateTransition.java
@@ -77,18 +77,28 @@ public class ServiceStateTransition {
logger.debug("{} transitioned to ENABLED", controllerServiceNode);
enabledFutures.forEach(future -> future.complete(null));
+ } finally {
+ writeLock.unlock();
+ }
- final List<ComponentNode> referencingComponents = controllerServiceReference.findRecursiveReferences(ComponentNode.class);
- for (final ComponentNode component : referencingComponents) {
- component.performValidation();
- }
+ // We want to perform validation against other components outside of the write lock. Component validation could be expensive
+ // and more importantly could reference other controller services, which could result in a dead lock if we run the validation
+ // while holding this.writeLock.
+ final List<ComponentNode> referencingComponents = controllerServiceReference.findRecursiveReferences(ComponentNode.class);
+ for (final ComponentNode component : referencingComponents) {
+ component.performValidation();
+ }
+ // Now that the write lock was relinquished in order to perform validation on referencing components, we must re-acquire it
+ // in order to signal that a state change has completed.
+ writeLock.lock();
+ try {
stateChangeCondition.signalAll();
-
- return true;
} finally {
writeLock.unlock();
}
+
+ return true;
}
public boolean transitionToDisabling(final ControllerServiceState expectedState, final CompletableFuture<?> disabledFuture) {