use of io.cdap.cdap.app.runtime.WorkflowDataProvider in project cdap by caskdata.
the class DefaultProgramWorkflowRunner method blockForCompletion.
/**
* Adds a listener to the {@link ProgramController} and blocks for completion.
*
* @param closeable a {@link Closeable} to call when the program execution completed
* @param controller the {@link ProgramController} for the program
* @throws Exception if the execution failed
*/
private void blockForCompletion(final Closeable closeable, final ProgramController controller) throws Exception {
// Execute the program.
final SettableFuture<Void> completion = SettableFuture.create();
controller.addListener(new AbstractListener() {
@Override
public void init(ProgramController.State currentState, @Nullable Throwable cause) {
switch(currentState) {
case COMPLETED:
completed();
break;
case KILLED:
killed();
break;
case ERROR:
error(cause);
break;
}
}
@Override
public void completed() {
Closeables.closeQuietly(closeable);
Set<Operation> fieldLineageOperations = new HashSet<>();
if (controller instanceof WorkflowDataProvider) {
fieldLineageOperations.addAll(((WorkflowDataProvider) controller).getFieldLineageOperations());
}
nodeStates.put(nodeId, new WorkflowNodeState(nodeId, NodeStatus.COMPLETED, fieldLineageOperations, controller.getRunId().getId(), null));
completion.set(null);
}
@Override
public void killed() {
Closeables.closeQuietly(closeable);
nodeStates.put(nodeId, new WorkflowNodeState(nodeId, NodeStatus.KILLED, controller.getRunId().getId(), null));
completion.set(null);
}
@Override
public void error(Throwable cause) {
Closeables.closeQuietly(closeable);
nodeStates.put(nodeId, new WorkflowNodeState(nodeId, NodeStatus.FAILED, controller.getRunId().getId(), cause));
completion.setException(cause);
}
}, Threads.SAME_THREAD_EXECUTOR);
// Block for completion.
try {
completion.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof Exception) {
throw (Exception) cause;
}
throw Throwables.propagate(cause);
} catch (InterruptedException e) {
try {
Futures.getUnchecked(controller.stop());
} catch (Throwable t) {
// no-op
}
// reset the interrupt
Thread.currentThread().interrupt();
}
}
use of io.cdap.cdap.app.runtime.WorkflowDataProvider in project cdap by caskdata.
the class DefaultProgramWorkflowRunner method runAndWait.
private void runAndWait(ProgramRunner programRunner, Program program, ProgramOptions options) throws Exception {
Closeable closeable = createCloseable(programRunner, program);
// Publish the program's starting state
RunId runId = ProgramRunners.getRunId(options);
String twillRunId = options.getArguments().getOption(ProgramOptionConstants.TWILL_RUN_ID);
ProgramDescriptor programDescriptor = new ProgramDescriptor(program.getId(), program.getApplicationSpecification());
programStateWriter.start(program.getId().run(runId), options, twillRunId, programDescriptor);
ProgramController controller;
try {
controller = programRunner.run(program, options);
} catch (Throwable t) {
// If there is any exception when running the program, close the program to release resources.
// Otherwise it will be released when the execution completed.
programStateWriter.error(program.getId().run(runId), t);
Closeables.closeQuietly(closeable);
throw t;
}
blockForCompletion(closeable, controller);
if (controller instanceof WorkflowDataProvider) {
updateWorkflowToken(((WorkflowDataProvider) controller).getWorkflowToken());
} else {
// This shouldn't happen
throw new IllegalStateException("No WorkflowToken available after program completed: " + program.getId());
}
}
Aggregations