private void handleProcessorNode(ProcessorNode processorNode, TopologyBuilder topologyBuilder) { if (processorNode.getProcessor() instanceof StatefulProcessor) { statefulProcessorCount++; Set<ProcessorNode> initialNodes = initialProcessors( curGroup.isEmpty() ? Collections.singletonList(processorNode) : curGroup); Set<Window<?, ?>> windows = getWindowParams(initialNodes); // if we get more than one stateful operation, we need to process the // current group so that we have one stateful operation per stateful bolt if (statefulProcessorCount > 1 || !windows.isEmpty()) { if (!curGroup.isEmpty()) { processCurGroup(topologyBuilder); } else if (!windows.isEmpty()) { // a stateful processor immediately follows a window specification splitStatefulProcessor(processorNode, topologyBuilder); } statefulProcessorCount = 1; } } curGroup.add(processorNode); }
} else if (node instanceof PartitionNode) { updateNodeGroupingInfo((PartitionNode) node); processCurGroup(topologyBuilder); } else if (node instanceof WindowNode) { updateWindowInfo((WindowNode) node); processCurGroup(topologyBuilder); } else if (node instanceof SinkNode) { processCurGroup(topologyBuilder); addSink(topologyBuilder, (SinkNode) node); processCurGroup(topologyBuilder); mayBeAddTsField(); return topologyBuilder.createTopology();
private void splitStatefulProcessor(ProcessorNode processorNode, TopologyBuilder topologyBuilder) { for (Node parent : StreamUtil.<Node>getParents(graph, processorNode)) { ProcessorNode identity = new ProcessorNode(new MapProcessor<>(new IdentityFunction<>()), UniqueIdGen.getInstance().getUniqueStreamId(), parent.getOutputFields()); addNode(parent, identity); graph.removeEdge(parent, processorNode); processorNode.removeParentStreams(parent); addNode(identity, processorNode); curGroup.add(identity); } processCurGroup(topologyBuilder); }