while (true) {
final ExecutionState previousState = this.executionState.get();
if (previousState == ExecutionState.CANCELED) {
return new TaskCancelResult(getID(), AbstractTaskResult.ReturnCode.SUCCESS);
}
if (previousState == ExecutionState.FAILED) {
return new TaskCancelResult(getID(), AbstractTaskResult.ReturnCode.SUCCESS);
}
if (previousState == ExecutionState.FINISHED) {
return new TaskCancelResult(getID(), AbstractTaskResult.ReturnCode.SUCCESS);
}
// The vertex has already received a cancel request
if (previousState == ExecutionState.CANCELING) {
return new TaskCancelResult(getID(), ReturnCode.SUCCESS);
}
// Do not trigger the cancel request when vertex is in state STARTING, this might cause a race between RPC
// calls.
if (previousState == ExecutionState.STARTING) {
this.cancelRequested.set(true);
// We had a race, so we unset the flag and take care of cancellation ourselves
if (this.executionState.get() != ExecutionState.STARTING) {
this.cancelRequested.set(false);
continue;
}
return new TaskCancelResult(getID(), AbstractTaskResult.ReturnCode.SUCCESS);
}
// Check if we had a race. If state change is accepted, send cancel request
if (compareAndUpdateExecutionState(previousState, ExecutionState.CANCELING)) {
if (this.groupVertex.getStageNumber() != this.executionGraph.getIndexOfCurrentExecutionStage()) {
// Set to canceled directly
updateExecutionState(ExecutionState.CANCELED, null);
return new TaskCancelResult(getID(), AbstractTaskResult.ReturnCode.SUCCESS);
}
if (previousState != ExecutionState.RUNNING && previousState != ExecutionState.FINISHING) {
// Set to canceled directly
updateExecutionState(ExecutionState.CANCELED, null);
return new TaskCancelResult(getID(), AbstractTaskResult.ReturnCode.SUCCESS);
}
final AllocatedResource ar = this.allocatedResource.get();
if (ar == null) {
final TaskCancelResult result = new TaskCancelResult(getID(),
AbstractTaskResult.ReturnCode.NO_INSTANCE);
result.setDescription("Assigned instance of vertex " + this.toString() + " is null!");
return result;
}
try {
return ar.getInstance().cancelTask(this.vertexID);
} catch (IOException e) {
final TaskCancelResult result = new TaskCancelResult(getID(),
AbstractTaskResult.ReturnCode.IPC_ERROR);
result.setDescription(StringUtils.stringifyException(e));
return result;
}
}
}
}