use of com.hazelcast.jet.impl.TerminationMode.CANCEL_GRACEFUL in project hazelcast by hazelcast.
the class MasterJobContext method getErrorFromResponses.
/**
* <ul>
* <li>Returns {@code null} if there is no failure
* <li>Returns a {@link CancellationException} if the job is cancelled
* forcefully.
* <li>Returns a {@link JobTerminateRequestedException} if the current
* execution is stopped due to a requested termination, except for
* CANCEL_GRACEFUL, in which case CancellationException is returned.
* <li>If there is at least one user failure, such as an exception in user
* code (restartable or not), then returns that failure.
* <li>Otherwise, the failure is because a job participant has left the
* cluster. In that case, it returns {@code TopologyChangeException} so
* that the job will be restarted
* </ul>
*/
private Throwable getErrorFromResponses(String opName, Collection<Map.Entry<MemberInfo, Object>> responses) {
if (isCancelled()) {
logger.fine(mc.jobIdString() + " to be cancelled after " + opName);
return new CancellationException();
}
Map<Boolean, List<Entry<Address, Object>>> grouped = responses.stream().map(en -> entry(en.getKey().getAddress(), en.getValue())).collect(partitioningBy(e1 -> e1.getValue() instanceof Throwable));
int successfulMembersCount = grouped.getOrDefault(false, emptyList()).size();
if (successfulMembersCount == mc.executionPlanMap().size()) {
logger.fine(opName + " of " + mc.jobIdString() + " was successful");
return null;
}
List<Entry<Address, Object>> failures = grouped.getOrDefault(true, emptyList());
if (!failures.isEmpty()) {
logger.fine(opName + " of " + mc.jobIdString() + " has failures: " + failures);
}
// other exceptions, ignore this and handle the other exception.
if (failures.stream().allMatch(entry -> entry.getValue() instanceof TerminatedWithSnapshotException)) {
assert opName.equals("Execution") : "opName is '" + opName + "', expected 'Execution'";
logger.fine(opName + " of " + mc.jobIdString() + " terminated after a terminal snapshot");
TerminationMode mode = requestedTerminationMode;
assert mode != null && mode.isWithTerminalSnapshot() : "mode=" + mode;
return mode == CANCEL_GRACEFUL ? new CancellationException() : new JobTerminateRequestedException(mode);
}
// If all exceptions are of certain type, treat it as TopologyChangedException
Map<Boolean, List<Entry<Address, Object>>> splitFailures = failures.stream().collect(Collectors.partitioningBy(e -> e.getValue() instanceof CancellationException || e.getValue() instanceof TerminatedWithSnapshotException || isTopologyException((Throwable) e.getValue())));
List<Entry<Address, Object>> topologyFailures = splitFailures.getOrDefault(true, emptyList());
List<Entry<Address, Object>> otherFailures = splitFailures.getOrDefault(false, emptyList());
if (!otherFailures.isEmpty()) {
return (Throwable) otherFailures.get(0).getValue();
} else {
return new TopologyChangedException("Causes from members: " + topologyFailures);
}
}
Aggregations