NIFI-7231: move controller service validation out of synchronized block for enabling

This closes #4118.

Signed-off-by: Mark Payne <markap14@hotmail.com>
This commit is contained in:
Mark Bean 2020-03-06 17:18:09 +00:00 committed by Mark Payne
parent cca54f7ff2
commit f4b65afb64
3 changed files with 12 additions and 17 deletions

View File

@ -37,4 +37,8 @@ public class ValidationState {
public Collection<ValidationResult> getValidationErrors() {
return validationErrors;
}
public String toString() {
return status.toString();
}
}

View File

@ -17,8 +17,6 @@
package org.apache.nifi.controller.service;
import org.apache.nifi.controller.ComponentNode;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@ -31,15 +29,10 @@ public class ServiceStateTransition {
private final List<CompletableFuture<?>> enabledFutures = new ArrayList<>();
private final List<CompletableFuture<?>> disabledFutures = new ArrayList<>();
private final ControllerServiceNode serviceNode;
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock writeLock = rwLock.writeLock();
private final Lock readLock = rwLock.readLock();
public ServiceStateTransition(final ControllerServiceNode serviceNode) {
this.serviceNode = serviceNode;
}
public boolean transitionToEnabling(final ControllerServiceState expectedState, final CompletableFuture<?> enabledFuture) {
writeLock.lock();
try {
@ -64,8 +57,6 @@ public class ServiceStateTransition {
state = ControllerServiceState.ENABLED;
validateReferences(serviceNode);
enabledFutures.forEach(future -> future.complete(null));
return true;
} finally {
@ -73,13 +64,6 @@ public class ServiceStateTransition {
}
}
private void validateReferences(final ControllerServiceNode service) {
final List<ComponentNode> referencingComponents = service.getReferences().findRecursiveReferences(ComponentNode.class);
for (final ComponentNode component : referencingComponents) {
component.performValidation();
}
}
public boolean transitionToDisabling(final ControllerServiceState expectedState, final CompletableFuture<?> disabledFuture) {
writeLock.lock();
try {

View File

@ -111,7 +111,7 @@ public class StandardControllerServiceNode extends AbstractComponentNode impleme
this.serviceProvider = serviceProvider;
this.active = new AtomicBoolean();
setControllerServiceAndProxy(implementation, proxiedControllerService, invocationHandler);
stateTransition = new ServiceStateTransition(this);
stateTransition = new ServiceStateTransition();
}
@Override
@ -436,6 +436,7 @@ public class StandardControllerServiceNode extends AbstractComponentNode impleme
synchronized (active) {
shouldEnable = active.get() && stateTransition.enable(); // Transitioning the state to ENABLED will complete our future.
}
validateReferences();
if (!shouldEnable) {
LOG.info("Disabling service {} after it has been enabled due to disable action being initiated.", service);
@ -474,6 +475,12 @@ public class StandardControllerServiceNode extends AbstractComponentNode impleme
return future;
}
private void validateReferences() {
final List<ComponentNode> referencingComponents = getReferences().findRecursiveReferences(ComponentNode.class);
for (final ComponentNode component : referencingComponents) {
component.performValidation();
}
}
/**
* Will atomically disable this service by invoking its @OnDisabled operation.