@Override public void processElement(WindowedValue<KeyedWorkItem<K, V>> element) throws Exception { KeyedWorkItem<K, V> workItem = element.getValue(); K key = workItem.key(); UncommittedBundle<KV<K, Iterable<V>>> bundle = evaluationContext.createBundle(application.getOutput()); outputBundles.add(bundle); CopyOnAccessInMemoryStateInternals<K> stateInternals = (CopyOnAccessInMemoryStateInternals<K>) stepContext.stateInternals(); DirectTimerInternals timerInternals = stepContext.timerInternals(); ReduceFnRunner<K, V, Iterable<V>, BoundedWindow> reduceFnRunner = new ReduceFnRunner<>( key, windowingStrategy, ExecutableTriggerStateMachine.create( TriggerStateMachines.stateMachineForTrigger(windowingStrategy.getTrigger())), stateInternals, timerInternals, new DirectWindowingInternals<>(bundle), droppedDueToClosedWindow, reduceFn, evaluationContext.getPipelineOptions()); // Drop any elements within expired windows reduceFnRunner.processElements( dropExpiredWindows(key, workItem.elementsIterable(), timerInternals)); for (TimerData timer : workItem.timersIterable()) { reduceFnRunner.onTimer(timer); } reduceFnRunner.persist(); }
@Override public TransformResult finishBundle() throws Exception { // State is initialized within the constructor. It can never be null. CopyOnAccessInMemoryStateInternals<?> state = stepContext.commitState(); return StepTransformResult.withHold(application, state.getEarliestWatermarkHold()) .withState(state) .addOutput(outputBundles) .withTimerUpdate(stepContext.getTimerUpdate()) .withAggregatorChanges(aggregatorChanges) .addUnprocessedElements(unprocessedElements.build()) .build(); }