@Override
public void executionStateChanged(final JobID jobID, final ExecutionVertexID vertexID,
final ExecutionState newExecutionState, final String optionalMessage) {
final ExecutionGraph eg = this.executionVertex.getExecutionGraph();
// Check if we can deploy a new pipeline.
if (newExecutionState == ExecutionState.FINISHING) {
final ExecutionPipeline pipeline = this.executionVertex.getExecutionPipeline();
if (!pipeline.isFinishing()) {
// Some tasks of the pipeline are still running
return;
}
// Find another vertex in the group which is still in SCHEDULED state and get its pipeline.
final ExecutionGroupVertex groupVertex = this.executionVertex.getGroupVertex();
for (int i = 0; i < groupVertex.getCurrentNumberOfGroupMembers(); ++i) {
final ExecutionVertex groupMember = groupVertex.getGroupMember(i);
if (groupMember.compareAndUpdateExecutionState(ExecutionState.SCHEDULED, ExecutionState.ASSIGNED)) {
final ExecutionPipeline pipelineToBeDeployed = groupMember.getExecutionPipeline();
pipelineToBeDeployed.setAllocatedResource(this.executionVertex.getAllocatedResource());
pipelineToBeDeployed.updateExecutionState(ExecutionState.ASSIGNED);
this.scheduler.deployAssignedPipeline(pipelineToBeDeployed);
return;
}
}
}
if (newExecutionState == ExecutionState.CANCELED || newExecutionState == ExecutionState.FINISHED) {
synchronized (eg) {
if (this.scheduler.getVerticesToBeRestarted().remove(this.executionVertex.getID()) != null) {
if (eg.getJobStatus() == InternalJobStatus.FAILING) {
return;
}
this.executionVertex.updateExecutionState(ExecutionState.ASSIGNED, "Restart as part of recovery");
// Run through the deployment procedure
this.scheduler.deployAssignedVertices(this.executionVertex);
return;
}
}
}
if (newExecutionState == ExecutionState.FINISHED || newExecutionState == ExecutionState.CANCELED
|| newExecutionState == ExecutionState.FAILED) {
// Check if instance can be released
this.scheduler.checkAndReleaseAllocatedResource(eg, this.executionVertex.getAllocatedResource());
}
// In case of an error, check if the vertex shall be recovered
if (newExecutionState == ExecutionState.FAILED) {
if (this.executionVertex.decrementRetriesLeftAndCheck()) {
final Set<ExecutionVertex> assignedVertices = new HashSet<ExecutionVertex>();
if (RecoveryLogic.recover(this.executionVertex, this.scheduler.getVerticesToBeRestarted(),
assignedVertices)) {
if (RecoveryLogic.hasInstanceAssigned(this.executionVertex)) {
// Run through the deployment procedure
this.scheduler.deployAssignedVertices(assignedVertices);
}
} else {
// Make sure the map with the vertices to be restarted is cleaned up properly
synchronized (eg) {
final Iterator<ExecutionVertex> it = this.scheduler.getVerticesToBeRestarted().values()
.iterator();
while (it.hasNext()) {
if (eg.equals(it.next().getExecutionGraph())) {
it.remove();
}
}
}