use of org.knime.core.node.workflow.FlowLoopContext.RestoredFlowLoopContext in project knime-core by knime.
the class WorkflowManager method doBeforeExecution.
/**
* Call-back from NodeContainer called before node is actually executed. The argument node is in usually a
* {@link SingleNodeContainer}, although it can also be a metanode (i.e. a <code>WorkflowManager</code>), which is
* executed remotely (execution takes place as a single operation).
*
* @param nc node whose execution is about to start
* @throws IllegalFlowObjectStackException If loop end nodes have problems identifying their start node
*/
void doBeforeExecution(final NodeContainer nc) {
assert !nc.getID().equals(this.getID());
assert !nc.isLocalWFM() : "No execution of local metanodes";
try (WorkflowLock lock = lock()) {
// allow NNC to update states etc
LOGGER.debug(nc.getNameWithID() + " doBeforeExecution");
nc.getNodeTimer().startExec();
if (nc instanceof SingleNodeContainer) {
FlowObjectStack flowObjectStack = nc.getFlowObjectStack();
FlowScopeContext fsc = flowObjectStack.peek(FlowScopeContext.class);
// if the node is in a subnode the subnode may be part of restored loop, see AP-7585
FlowLoopContext subnodeOuterFlowLoopContext = flowObjectStack.peekOptional(FlowSubnodeScopeContext.class).map(s -> s.getOuterFlowScopeContext(FlowLoopContext.class)).orElse(null);
if (fsc instanceof RestoredFlowLoopContext || subnodeOuterFlowLoopContext instanceof RestoredFlowLoopContext) {
throw new IllegalFlowObjectStackException("Can't continue loop as the workflow was restored with the loop being partially " + "executed. Reset loop start and execute entire loop again.");
}
if (nc instanceof NativeNodeContainer) {
NativeNodeContainer nnc = (NativeNodeContainer) nc;
if (nnc.isModelCompatibleTo(ScopeEndNode.class)) {
// if this is an END to a loop/scope, make sure it knows its head
if (fsc == null) {
LOGGER.debug("Incoming flow object stack for " + nnc.getNameWithID() + ":\n" + flowObjectStack.toDeepString());
if (nnc.isModelCompatibleTo(LoopEndNode.class)) {
throw new IllegalFlowObjectStackException("Encountered loop-end without corresponding head!");
} else {
throw new IllegalFlowObjectStackException("Encountered scope-end without corresponding head!");
}
}
NodeContainer headNode = m_workflow.getNode(fsc.getOwner());
if (headNode == null) {
if (nnc.isModelCompatibleTo(LoopEndNode.class)) {
throw new IllegalFlowObjectStackException("Loop start and end nodes are not in the" + " same workflow");
} else {
throw new IllegalFlowObjectStackException("Scope start and end nodes are not in the" + " same workflow");
}
} else if (headNode instanceof NativeNodeContainer && ((NativeNodeContainer) headNode).isModelCompatibleTo(ScopeStartNode.class)) {
// check that the start and end nodes have compatible flow scope contexts
Class<? extends FlowScopeContext> endNodeFlowScopeContext = ((ScopeEndNode<?>) nnc.getNodeModel()).getFlowScopeContextClass();
if (!endNodeFlowScopeContext.isAssignableFrom(fsc.getClass())) {
if (nnc.isModelCompatibleTo(LoopEndNode.class)) {
throw new IllegalFlowObjectStackException("Encountered loop-end without compatible head!");
} else {
throw new IllegalFlowObjectStackException("Encountered scope-end without compatible head!");
}
}
}
assert ((NativeNodeContainer) headNode).getNode().getNodeModel().equals(nnc.getNode().getScopeStartNode(ScopeStartNode.class).orElse(null));
} else if (nnc.isModelCompatibleTo(LoopStartNode.class)) {
pushFlowContextForLoopIteration(nnc);
} else {
// or not if it's any other type of node
nnc.getNode().setScopeStartNode(null);
}
}
}
nc.performStateTransitionEXECUTING();
lock.queueCheckForNodeStateChangeNotification(true);
}
}
use of org.knime.core.node.workflow.FlowLoopContext.RestoredFlowLoopContext in project knime-core by knime.
the class FileSingleNodeContainerPersistor method loadFlowObjects.
/**
* Load from variables.
*
* @param settings to load from, ignored in this implementation (flow variables added in later versions)
* @return an empty list.
* @throws InvalidSettingsException if that fails for any reason.
*/
List<FlowObject> loadFlowObjects(final NodeSettingsRO settings) throws InvalidSettingsException {
if (getLoadVersion().isOlderThan(LoadVersion.V200)) {
return Collections.emptyList();
}
List<FlowObject> result = new ArrayList<FlowObject>();
NodeSettingsRO stackSet;
if (getLoadVersion().isOlderThan(LoadVersion.V220)) {
stackSet = settings.getNodeSettings("scope_stack");
} else {
stackSet = settings.getNodeSettings("flow_stack");
}
for (String key : stackSet.keySet()) {
NodeSettingsRO sub = stackSet.getNodeSettings(key);
String type = sub.getString("type");
if ("variable".equals(type)) {
FlowVariable v = FlowVariable.load(sub);
result.add(v);
} else if ("loopcontext".equals(type)) {
result.add(new RestoredFlowLoopContext());
// int tailID = sub.getInt("tailID");
} else if ("loopcontext_execute".equals(type)) {
result.add(new InnerFlowLoopExecuteMarker());
} else if ("loopcontext_inactive".equals(type)) {
FlowLoopContext flc = new FlowLoopContext();
flc.inactiveScope(true);
result.add(flc);
} else if ("flowcapturecontext".equals(type)) {
result.add(new FlowCaptureContext());
} else if ("flowcapturecontext_inactive".equals(type)) {
FlowScopeContext slc = new FlowCaptureContext();
slc.inactiveScope(true);
result.add(slc);
} else if ("scopecontext".equals(type)) {
result.add(new FlowScopeContext());
} else if ("scopecontext_inactive".equals(type)) {
FlowScopeContext slc = new FlowScopeContext();
slc.inactiveScope(true);
result.add(slc);
} else {
throw new InvalidSettingsException("Unknown flow object type: " + type);
}
}
return result;
}
Aggregations