@Override
public ConnectionInfoLookupResponse lookupConnectionInfo(InstanceConnectionInfo caller, JobID jobID, ChannelID sourceChannelID) {
final ExecutionGraph eg = this.scheduler.getExecutionGraphByID(jobID);
if (eg == null) {
LOG.error("Cannot find execution graph to job ID " + jobID);
return ConnectionInfoLookupResponse.createReceiverNotFound();
}
final InternalJobStatus jobStatus = eg.getJobStatus();
if (jobStatus == InternalJobStatus.FAILING || jobStatus == InternalJobStatus.CANCELING) {
return ConnectionInfoLookupResponse.createJobIsAborting();
}
final ExecutionEdge edge = eg.getEdgeByID(sourceChannelID);
if (edge == null) {
LOG.error("Cannot find execution edge associated with ID " + sourceChannelID);
return ConnectionInfoLookupResponse.createReceiverNotFound();
}
if (sourceChannelID.equals(edge.getInputChannelID())) {
// Request was sent from an input channel
final ExecutionVertex connectedVertex = edge.getOutputGate().getVertex();
final AbstractInstance assignedInstance = connectedVertex.getAllocatedResource().getInstance();
if (assignedInstance == null) {
LOG.error("Cannot resolve lookup: vertex found for channel ID " + edge.getOutputGateIndex()
+ " but no instance assigned");
// LOG.info("Created receiverNotReady for " + connectedVertex + " 1");
return ConnectionInfoLookupResponse.createReceiverNotReady();
}
// Check execution state
final ExecutionState executionState = connectedVertex.getExecutionState();
if (executionState == ExecutionState.FINISHED) {
// that should not happen. if there is data pending, the receiver cannot be ready
return ConnectionInfoLookupResponse.createReceiverNotFound();
}
// running is common, finishing is happens when the lookup is for the close event
if (executionState != ExecutionState.RUNNING && executionState != ExecutionState.FINISHING) {
// LOG.info("Created receiverNotReady for " + connectedVertex + " in state " + executionState + " 2");
return ConnectionInfoLookupResponse.createReceiverNotReady();
}
if (assignedInstance.getInstanceConnectionInfo().equals(caller)) {
// Receiver runs on the same task manager
return ConnectionInfoLookupResponse.createReceiverFoundAndReady(edge.getOutputChannelID());
} else {
// Receiver runs on a different task manager
final InstanceConnectionInfo ici = assignedInstance.getInstanceConnectionInfo();
final InetSocketAddress isa = new InetSocketAddress(ici.address(), ici.dataPort());
return ConnectionInfoLookupResponse.createReceiverFoundAndReady(new RemoteReceiver(isa, edge.getConnectionID()));
}
}
// else, the request is for an output channel
// Find vertex of connected input channel
final ExecutionVertex targetVertex = edge.getInputGate().getVertex();
// Check execution state
final ExecutionState executionState = targetVertex.getExecutionState();
// check whether the task needs to be deployed
if (executionState != ExecutionState.RUNNING && executionState != ExecutionState.FINISHING && executionState != ExecutionState.FINISHED) {
if (executionState == ExecutionState.ASSIGNED) {
final Runnable command = new Runnable() {
@Override
public void run() {
scheduler.deployAssignedVertices(targetVertex);
}
};
eg.executeCommand(command);
}
// LOG.info("Created receiverNotReady for " + targetVertex + " in state " + executionState + " 3");
return ConnectionInfoLookupResponse.createReceiverNotReady();
}