use of com.hazelcast.jet.impl.exception.TerminatedWithSnapshotException 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);
}
}
use of com.hazelcast.jet.impl.exception.TerminatedWithSnapshotException in project hazelcast by hazelcast.
the class ExecutionContext method beginExecution.
/**
* Starts local execution of job by submitting tasklets to execution service. If
* execution was cancelled earlier then execution will not be started.
* <p>
* Returns a future which is completed only when all tasklets are completed. If
* execution was already cancelled before this method is called then the returned
* future is completed immediately. The future returned can't be cancelled,
* instead {@link #terminateExecution} should be used.
*/
public CompletableFuture<Void> beginExecution(TaskletExecutionService taskletExecService) {
synchronized (executionLock) {
if (executionFuture != null) {
// beginExecution was already called or execution was cancelled before it started.
LoggingUtil.logFine(logger, "%s: execution started after cancelled", jobNameAndExecutionId());
return executionFuture;
} else {
// begin job execution
ClassLoader cl = jetServiceBackend.getJobClassLoaderService().getClassLoader(jobId);
if (cl == null) {
cl = nodeEngine.getConfigClassLoader();
}
executionFuture = taskletExecService.beginExecute(tasklets, cancellationFuture, cl).whenComplete(withTryCatch(logger, (r, t) -> setCompletionTime())).thenApply(res -> {
// We ignore this for now.
if (snapshotContext.isTerminalSnapshot()) {
throw new TerminatedWithSnapshotException();
}
return res;
});
startTime.set(System.currentTimeMillis());
}
return executionFuture;
}
}
Aggregations