use of cz.metacentrum.perun.engine.exceptions.TaskExecutionException in project perun by CESNET.
the class GenCollectorTest method testGenCollectorTaskException.
@Test
public void testGenCollectorTaskException() throws Exception {
when(schedulingPoolMock.getGeneratedTasksQueue()).thenReturn(generatedTasksQueue);
when(genCompletionServiceMock.blockingTake()).thenThrow(new TaskExecutionException(task1, "Test err"));
doReturn(false, true).when(spy).shouldStop();
spy.run();
verify(jmsQueueManagerMock, times(1)).reportTaskStatus(eq(task1.getId()), eq(GENERROR), anyLong());
verify(schedulingPoolMock, times(1)).removeTask(task1.getId());
assertTrue(generatedTasksQueue.isEmpty());
}
use of cz.metacentrum.perun.engine.exceptions.TaskExecutionException in project perun by CESNET.
the class SendCollectorTest method sendCollectorTaskExceptionTest.
@Test
public void sendCollectorTaskExceptionTest() throws Exception {
task1.setStatus(Task.TaskStatus.SENDING);
doReturn(sendTask1).doThrow(new TaskExecutionException(sendTask2.getTask(), sendTask2.getDestination(), "Test error")).when(sendCompletionServiceMock).blockingTake();
doReturn(false, false, true).when(spy).shouldStop();
doReturn(task1).when(schedulingPoolMock).getTask(task1.getId());
spy.run();
// SENDING instead of SENT, because only real SendWorker switches state
assertEquals(SENDING, sendTask1.getStatus());
// since one of SendTasks failed, Task status is changed to SENDERROR
assertEquals(Task.TaskStatus.SENDERROR, task1.getStatus());
verify(schedulingPoolMock, times(2)).decreaseSendTaskCount(task1, 1);
verify(jmsQueueManagerMock, times(2)).reportTaskResult(null);
}
use of cz.metacentrum.perun.engine.exceptions.TaskExecutionException in project perun by CESNET.
the class GenWorkerImpl method call.
@Override
public Task call() throws TaskExecutionException {
getTask().setGenStartTime(LocalDateTime.now());
Service service = getTask().getService();
log.info("[{}] Executing GEN worker for Task with Service ID: {} and Facility ID: {}.", getTask().getId(), getTask().getServiceId(), getTask().getFacilityId());
ProcessBuilder pb = new ProcessBuilder(service.getScript(), "-f", String.valueOf(getTask().getFacilityId()));
try {
// start the script and wait for results
super.execute(pb);
// set gen end time
getTask().setGenEndTime(LocalDateTime.now());
if (getReturnCode() != 0) {
log.error("[{}] GEN worker failed for Task. Ret code {}, STDOUT: {}, STDERR: {}", getTask().getId(), getReturnCode(), getStdout(), getStderr());
throw new TaskExecutionException(task, getReturnCode(), getStdout(), getStderr());
} else {
log.info("[{}] GEN worker finished for Task. Ret code {}, STDOUT: {}, STDERR: {}", getTask().getId(), getReturnCode(), getStdout(), getStderr());
return getTask();
}
} catch (IOException e) {
log.error("[{}] GEN worker failed for Task. IOException: {}.", task.getId(), e);
throw new TaskExecutionException(task, 2, "", e.getMessage());
} catch (InterruptedException e) {
log.warn("[{}] GEN worker failed for Task. Execution was interrupted {}.", task.getId(), e);
throw new TaskExecutionException(task, 1, "", e.getMessage());
}
}
use of cz.metacentrum.perun.engine.exceptions.TaskExecutionException in project perun by CESNET.
the class GenCollector method run.
@Override
public void run() {
BlockingDeque<Task> generatedTasks = schedulingPool.getGeneratedTasksQueue();
while (!shouldStop()) {
try {
Task task = genCompletionService.blockingTake();
// set ok status immediately
task.setStatus(Task.TaskStatus.GENERATED);
// report to Dispatcher
try {
jmsQueueManager.reportTaskStatus(task.getId(), task.getStatus(), task.getGenEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
} catch (JMSException e) {
jmsErrorLog(task.getId(), task.getStatus());
}
// push Task to generated
if (task.isPropagationForced()) {
generatedTasks.putFirst(task);
} else {
generatedTasks.put(task);
}
} catch (InterruptedException e) {
String errorStr = "Thread collecting generated Tasks was interrupted.";
log.error(errorStr);
throw new RuntimeException(errorStr, e);
} catch (TaskExecutionException e) {
// GEN Task failed
Task task = e.getTask();
if (task == null) {
log.error("GEN Task failed, but TaskExecutionException doesn't contained Task object! Tasks will be cleaned by PropagationMaintainer#endStuckTasks()");
} else {
task.setStatus(GENERROR);
for (Destination dest : task.getDestinations()) {
try {
jmsQueueManager.reportTaskResult(schedulingPool.createTaskResult(task.getId(), dest.getId(), e.getStderr(), e.getStdout(), e.getReturnCode(), task.getService()));
} catch (JMSException | InterruptedException ex) {
log.error("[{}] Error trying to reportTaskResult for Destination: {} to Dispatcher: {}", task.getId(), dest, ex);
}
}
try {
jmsQueueManager.reportTaskStatus(task.getId(), GENERROR, System.currentTimeMillis());
} catch (JMSException | InterruptedException e1) {
jmsErrorLog(task.getId(), task.getStatus());
}
try {
schedulingPool.removeTask(task.getId());
} catch (TaskStoreException e1) {
log.error("[{}] Could not remove error GEN Task from SchedulingPool: {}", task.getId(), e1);
}
}
} catch (Throwable ex) {
log.error("Unexpected exception in GenCollector thread. Stuck Tasks will be cleaned by PropagationMaintainer#endStuckTasks() later.", ex);
}
}
}
use of cz.metacentrum.perun.engine.exceptions.TaskExecutionException in project perun by CESNET.
the class SendCollector method run.
@Override
public void run() {
while (!shouldStop()) {
SendTask sendTask = null;
Task task = null;
Service service = null;
Destination destination = null;
String stderr;
String stdout;
int returnCode;
// FIXME - doesn't provide nice output and clog the log
log.debug(schedulingPool.getReport());
try {
sendTask = sendCompletionService.blockingTake();
task = sendTask.getTask();
/*
Set Task "sendEndTime" immediately for each done SendTask, so it's not considered as stuck
by PropagationMaintainer#endStuckTasks().
Like this we can maximally propagate for "rescheduleTime" for each Destination and not
all Destinations (whole Task). Default rescheduleTime is 3 hours * no.of destinations.
*/
task.setSendEndTime(LocalDateTime.now());
// XXX: why is this necessary? Rewriting status with every completed destination?
if (!Objects.equals(task.getStatus(), Task.TaskStatus.SENDERROR) && !Objects.equals(task.getStatus(), Task.TaskStatus.WARNING) && !Objects.equals(sendTask.getStatus(), SendTaskStatus.WARNING)) {
// keep SENDING status only if task previously hasn't failed
task.setStatus(Task.TaskStatus.SENDING);
} else if (!Objects.equals(task.getStatus(), Task.TaskStatus.SENDERROR) && sendTask.getStatus() == SendTaskStatus.WARNING) {
task.setStatus(Task.TaskStatus.WARNING);
}
destination = sendTask.getDestination();
stderr = sendTask.getStderr();
stdout = sendTask.getStdout();
returnCode = sendTask.getReturnCode();
service = sendTask.getTask().getService();
} catch (InterruptedException e) {
String errorStr = "Thread collecting sent SendTasks was interrupted.";
log.error("{}: {}", errorStr, e);
throw new RuntimeException(errorStr, e);
} catch (TaskExecutionException e) {
task = e.getTask();
/*
Set Task "sendEndTime" immediately for each done SendTask, so it's not considered as stuck
by PropagationMaintainer#endStuckTasks().
Like this we can maximally propagate for "rescheduleTime" for each Destination and not
all Destinations (whole Task). Default rescheduleTime is 3 hours * no.of destinations.
*/
task.setSendEndTime(LocalDateTime.now());
// set SENDERROR status immediately as first SendTask (Destination) fails
task.setStatus(Task.TaskStatus.SENDERROR);
destination = e.getDestination();
stderr = e.getStderr();
stdout = e.getStdout();
returnCode = e.getReturnCode();
service = task.getService();
log.error("[{}] Error occurred while sending Task to destination {}", task.getId(), e.getDestination());
} catch (Throwable ex) {
log.error("Unexpected exception in SendCollector thread. Stuck Tasks will be cleaned by PropagationMaintainer#endStuckTasks() later.", ex);
continue;
}
// this is just interesting cross-check
if (schedulingPool.getTask(task.getId()) == null) {
log.warn("[{}] Task retrieved from SendTask is no longer in SchedulingPool. Probably cleaning thread removed it before completion. " + "This might create possibility of running GEN and SEND of same Task together!", task.getId());
}
try {
// report TaskResult to Dispatcher for this SendTask (Destination)
jmsQueueManager.reportTaskResult(schedulingPool.createTaskResult(task.getId(), destination.getId(), stderr, stdout, returnCode, service));
} catch (JMSException | InterruptedException e1) {
log.error("[{}] Error trying to reportTaskResult for Destination: {} to Dispatcher: {}", task.getId(), destination, e1);
}
try {
// Decrease SendTasks count for Task
// Consequently, if count is <=1, Task is reported to Dispatcher
// as DONE/SENDERROR and removed from SchedulingPool (Engine).
schedulingPool.decreaseSendTaskCount(task, 1);
} catch (TaskStoreException e) {
log.error("[{}] Task {} could not be removed from SchedulingPool: {}", task.getId(), task, e);
}
}
}
Aggregations