[
https://issues.apache.org/jira/browse/NIFI-2032?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15340099#comment-15340099
]
ASF GitHub Bot commented on NIFI-2032:
--------------------------------------
Github user mcgilman commented on a diff in the pull request:
https://github.com/apache/nifi/pull/541#discussion_r67739510
--- Diff:
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceProvider.java
---
@@ -372,98 +369,32 @@ public void enableControllerService(final
ControllerServiceNode serviceNode) {
@Override
public void enableControllerServices(final
Collection<ControllerServiceNode> serviceNodes) {
- final Set<ControllerServiceNode> servicesToEnable = new
HashSet<>();
- // Ensure that all nodes are already disabled
- for (final ControllerServiceNode serviceNode : serviceNodes) {
- final ControllerServiceState curState = serviceNode.getState();
- if (ControllerServiceState.DISABLED.equals(curState)) {
- servicesToEnable.add(serviceNode);
- } else {
- logger.warn("Cannot enable {} because it is not disabled;
current state is {}", serviceNode, curState);
+ boolean shouldStart = true;
+
+ Iterator<ControllerServiceNode> serviceIter =
serviceNodes.iterator();
+ while (serviceIter.hasNext() && shouldStart) {
+ ControllerServiceNode controllerServiceNode =
serviceIter.next();
+ List<ControllerServiceNode> requiredServices =
((StandardControllerServiceNode)
controllerServiceNode).getRequiredControllerServices();
+ for (ControllerServiceNode requiredService : requiredServices)
{
+ if (!requiredService.isActive() &&
!serviceNodes.contains(requiredService)) {
+ shouldStart = false;
+ }
}
}
- // determine the order to load the services. We have to ensure
that if service A references service B, then B
- // is enabled first, and so on.
- final Map<String, ControllerServiceNode> idToNodeMap = new
HashMap<>();
- for (final ControllerServiceNode node : servicesToEnable) {
- idToNodeMap.put(node.getIdentifier(), node);
- }
-
- // We can have many Controller Services dependent on one another.
We can have many of these
- // disparate lists of Controller Services that are dependent on
one another. We refer to each
- // of these as a branch.
- final List<List<ControllerServiceNode>> branches =
determineEnablingOrder(idToNodeMap);
-
- if (branches.isEmpty()) {
- logger.info("No Controller Services to enable");
- return;
- } else {
- logger.info("Will enable {} Controller Services",
servicesToEnable.size());
- }
-
- final Set<ControllerServiceNode> enabledNodes =
Collections.synchronizedSet(new HashSet<ControllerServiceNode>());
- final ExecutorService executor =
Executors.newFixedThreadPool(Math.min(10, branches.size()), new ThreadFactory()
{
- @Override
- public Thread newThread(final Runnable r) {
- final Thread t =
Executors.defaultThreadFactory().newThread(r);
- t.setDaemon(true);
- t.setName("Enable Controller Services");
- return t;
- }
- });
-
- for (final List<ControllerServiceNode> branch : branches) {
- final Runnable enableBranchRunnable = new Runnable() {
+ if (shouldStart) {
+ List<ControllerServiceNode> services = new
ArrayList<>(serviceNodes);
+ Collections.sort(services, new
Comparator<ControllerServiceNode>() {
@Override
- public void run() {
- logger.debug("Enabling Controller Service Branch {}",
branch);
-
- for (final ControllerServiceNode serviceNode : branch)
{
- try {
- if (!enabledNodes.contains(serviceNode)) {
- enabledNodes.add(serviceNode);
-
- logger.info("Enabling {}", serviceNode);
- try {
- serviceNode.verifyCanEnable();
-
processScheduler.enableControllerService(serviceNode);
- } catch (final Exception e) {
- logger.error("Failed to enable " +
serviceNode + " due to " + e);
- if (logger.isDebugEnabled()) {
- logger.error("", e);
- }
-
- if (bulletinRepo != null) {
--- End diff --
Looks like we were creating a bulletin whenever we were unable to enable a
Controller Service.
> Processors could be started before the Controller Services that they depend on
> ------------------------------------------------------------------------------
>
> Key: NIFI-2032
> URL: https://issues.apache.org/jira/browse/NIFI-2032
> Project: Apache NiFi
> Issue Type: Bug
> Components: Core Framework
> Reporter: Mark Payne
> Assignee: Oleg Zhurakousky
> Priority: Critical
> Fix For: 1.0.0, 0.7.0
>
>
> in the StandardControllerServiceProvider, we enable a Collection of
> Controller Services but do so in the background with a limited number of
> threads. We need to ensure that all Controller Services have at least become
> ENABLING before returning from this method. Otherwise, Processors that depend
> on them could attempt to start. If this happens, the Processor will be
> invalid because it references a Disabled Controller Service. As a result, the
> Processor will not start. In a clustered environment, we will end up with
> inconsistent run states across the nodes.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)