private <T> void evaluateBundle( final AppliedPTransform<?, ?, ?> transform, final CommittedBundle<T> bundle, final CompletionCallback onComplete) { TransformExecutorService transformExecutor; if (isKeyed(bundle.getPCollection())) { final StepAndKey stepAndKey = StepAndKey.of(transform, bundle.getKey()); // This executor will remain reachable until it has executed all scheduled transforms. // The TransformExecutors keep a strong reference to the Executor, the ExecutorService keeps // a reference to the scheduled TransformExecutor callable. Follow-up TransformExecutors // (scheduled due to the completion of another TransformExecutor) are provided to the // ExecutorService before the Earlier TransformExecutor callable completes. transformExecutor = executorServices.getUnchecked(stepAndKey); } else { transformExecutor = parallelExecutorService; } Collection<ModelEnforcementFactory> enforcements = MoreObjects.firstNonNull( transformEnforcements.get(transform.getTransform().getClass()), Collections.<ModelEnforcementFactory>emptyList()); TransformExecutor<T> callable = TransformExecutor.create( evaluationContext, registry, enforcements, bundle, transform, onComplete, transformExecutor); outstandingWork.incrementAndGet(); transformExecutor.schedule(callable); }
/** Get an {@link ExecutionContext} for the provided {@link AppliedPTransform} and key. */ public InProcessExecutionContext getExecutionContext( AppliedPTransform<?, ?, ?> application, Object key) { StepAndKey stepAndKey = StepAndKey.of(application, key); return new InProcessExecutionContext( options.getClock(), key, (CopyOnAccessInMemoryStateInternals<Object>) applicationStateInternals.get(stepAndKey), watermarkManager.getWatermarks(application)); }
/** * Handle the provided {@link InProcessTransformResult}, produced after evaluating the provided * {@link CommittedBundle} (potentially null, if the result of a root {@link PTransform}). * * <p>The result is the output of running the transform contained in the {@link * InProcessTransformResult} on the contents of the provided bundle. * * @param completedBundle the bundle that was processed to produce the result. Potentially {@code * null} if the transform that produced the result is a root transform * @param completedTimers the timers that were delivered to produce the {@code completedBundle}, * or an empty iterable if no timers were delivered * @param result the result of evaluating the input bundle * @return the committed bundles contained within the handled {@code result} */ public CommittedResult handleResult( @Nullable CommittedBundle<?> completedBundle, Iterable<TimerData> completedTimers, InProcessTransformResult result) { Iterable<? extends CommittedBundle<?>> committedBundles = commitBundles(result.getOutputBundles()); // Update watermarks and timers EnumSet<OutputType> outputTypes = EnumSet.copyOf(result.getOutputTypes()); if (Iterables.isEmpty(committedBundles)) { outputTypes.remove(OutputType.BUNDLE); } else { outputTypes.add(OutputType.BUNDLE); } CommittedResult committedResult = CommittedResult.create( result, completedBundle == null ? null : completedBundle.withElements((Iterable) result.getUnprocessedElements()), committedBundles, outputTypes); watermarkManager.updateWatermarks( completedBundle, result.getTimerUpdate().withCompletedTimers(completedTimers), committedResult, result.getWatermarkHold()); // Update counters if (result.getCounters() != null) { mergedCounters.merge(result.getCounters()); } // Update state internals CopyOnAccessInMemoryStateInternals<?> theirState = result.getState(); if (theirState != null) { CopyOnAccessInMemoryStateInternals<?> committedState = theirState.commit(); StepAndKey stepAndKey = StepAndKey.of( result.getTransform(), completedBundle == null ? null : completedBundle.getKey()); if (!committedState.isEmpty()) { applicationStateInternals.put(stepAndKey, committedState); } else { applicationStateInternals.remove(stepAndKey); } } return committedResult; }