use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.
the class PropagationMaintainer method rescheduleDoneTasks.
/**
* Reschedule Tasks in DONE/WARNING state if their
* - source was updated
* - OR haven't run for X hours
* - OR have no end time set
* Reschedule also WAITING tasks (only when their source was updated).
*/
private void rescheduleDoneTasks() {
// Reschedule tasks in DONE that haven't been running for quite a while
log.info("Checking DONE/WARNING/WAITING tasks...");
for (Task task : schedulingPool.getTasksWithStatus(TaskStatus.DONE, TaskStatus.WARNING, TaskStatus.WAITING)) {
LocalDateTime tooManyHoursAgo = LocalDateTime.now().minusHours(oldRescheduleHours);
if (task.isSourceUpdated()) {
// source data has changed - re-schedule task
log.info("[{}] Task in {} state will be rescheduled, source data changed.", task.getId(), task.getStatus());
schedulingPool.scheduleTask(task, -1);
} else {
// data hasn't changed => check if its not too old
if (task.getEndTime() == null || task.getEndTime().isBefore(tooManyHoursAgo)) {
// they will get re-scheduled if stuck by endStuckTasks()
if (!TaskStatus.WAITING.equals(task.getStatus())) {
log.info("[{}] Task in {} state will be rescheduled, hasn't run for {} hours.", task.getId(), task.getStatus(), oldRescheduleHours);
schedulingPool.scheduleTask(task, -1);
}
} else {
log.trace("[{}] Task has finished recently or source data hasn't changed, leaving it for now.", task.getId());
}
}
}
}
use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.
the class EventProcessor method createTaskFromEvent.
/**
* Creates Task from Event data. Tries to resolve Service and Facility pairs from Event.
* Events for non existing entities are discarded.
*
* @param event Event to parse
* @throws ServiceNotExistsException When Service from Event doesn't exists anymore
* @throws InvalidEventMessageException When Message has invalid format.
* @throws InternalErrorException When implementation fails
* @throws PrivilegeException When dispatcher lack privileges to call core methods
*/
private void createTaskFromEvent(Event event) throws ServiceNotExistsException, InvalidEventMessageException, PrivilegeException {
Map<Facility, Set<Service>> resolvedServices = eventServiceResolver.resolveEvent(event.getData());
for (Entry<Facility, Set<Service>> map : resolvedServices.entrySet()) {
Facility facility = map.getKey();
for (Service service : map.getValue()) {
if (!service.isEnabled()) {
log.debug("Service not enabled: {}.", service);
continue;
}
if (((PerunBl) perun).getServicesManagerBl().isServiceBlockedOnFacility(service, facility)) {
log.debug("Service blocked on Facility: {} , {}.", service, facility);
continue;
}
// Check if all destinations are not blocked
try {
// init session
try {
if (sess == null) {
sess = perun.getPerunSession(new PerunPrincipal(dispatcherProperties.getProperty("perun.principal.name"), dispatcherProperties.getProperty("perun.principal.extSourceName"), dispatcherProperties.getProperty("perun.principal.extSourceType")), new PerunClient());
}
} catch (InternalErrorException e1) {
log.error("Error establishing perun session to create Task from Event: ", e1);
continue;
}
List<Destination> destinations = perun.getServicesManager().getDestinations(sess, service, facility);
if (destinations != null && !destinations.isEmpty()) {
Iterator<Destination> iter = destinations.iterator();
while (iter.hasNext()) {
Destination dest = iter.next();
if (((PerunBl) perun).getServicesManagerBl().isServiceBlockedOnDestination(service, dest.getId())) {
iter.remove();
}
}
if (destinations.isEmpty()) {
// All service destinations were blocked -> Task is denied to be sent to engine just like
// when service is blocked globally in Perun or on facility as a whole.
log.debug("{} blocked on all destinations on {}.", service, facility);
continue;
}
}
} catch (ServiceNotExistsException e) {
log.error("Service not exist: {}.", service);
} catch (FacilityNotExistsException e) {
log.error("Facility not exist: {}.", facility);
} catch (InternalErrorException | PrivilegeException e) {
log.error("{}", e);
}
// check for presence of task for this <Service, Facility> pair
// NOTE: this must be atomic enough to not create duplicate
// tasks in schedulingPool (are we running in parallel
// here?)
boolean isForced = determineForcedPropagation(event);
Task task = schedulingPool.getTask(facility, service);
if (task != null) {
// there already is a task in schedulingPool
// signal that task needs to regenerate data and be forced next time
task.setDestinations(null);
task.setSourceUpdated(true);
if (isForced)
task.setPropagationForced(true);
task.setRecurrence(0);
log.debug("[{}] Task is already in pool. Re-setting source updated and forced flags, {}.", task.getId(), task);
} else {
// no such task yet, create one
task = new Task();
task.setFacility(facility);
task.setService(service);
task.setStatus(TaskStatus.WAITING);
task.setRecurrence(0);
task.setDelay(service.getDelay());
task.setSchedule(LocalDateTime.now());
task.setSourceUpdated(false);
task.setPropagationForced(isForced);
try {
schedulingPool.addToPool(task);
log.debug("[{}] New Task added to pool. {}.", task.getId(), task);
} catch (TaskStoreException e) {
log.error("[{}] Could not add Task to pool. Task {} will be lost: {}", task.getId(), task, e);
}
schedulingPool.scheduleTask(task, -1);
}
}
}
}
use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.
the class TaskStoreTest method testAddEqualTasks.
@Test
public void testAddEqualTasks() throws Exception {
Task taskWW = new Task();
taskWW.setFacility(taskW.getFacility());
taskWW.setService(taskW.getService());
taskWW.setId(10);
taskStore.addTask(taskW);
exception.expect(TaskStoreException.class);
taskStore.addTask(taskWW);
}
use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.
the class SendPlanner method run.
@Override
public void run() {
BlockingQueue<Task> generatedTasks = schedulingPool.getGeneratedTasksQueue();
while (!shouldStop()) {
try {
Task task = generatedTasks.take();
// has destinations -> SENDING
if (task.getDestinations().isEmpty()) {
task.setStatus(Task.TaskStatus.ERROR);
try {
jmsQueueManager.reportTaskStatus(task.getId(), task.getStatus(), System.currentTimeMillis());
} catch (JMSException e) {
jmsLogError(task);
}
try {
schedulingPool.removeTask(task);
} catch (TaskStoreException e) {
log.error("[{}] Generated Task without destinations could not be removed from SchedulingPool: {}", task.getId(), e);
}
// skip to next generated Task
continue;
}
// Task has destinations
task.setStatus(Task.TaskStatus.SENDING);
// TODO - would be probably better to have this as one time call after first SendWorker is submitted
// TODO but then processing stuck tasks must reflect, that SENDING task might have sendStartTime=NULL
task.setSendStartTime(LocalDateTime.now());
schedulingPool.addSendTaskCount(task, task.getDestinations().size());
try {
jmsQueueManager.reportTaskStatus(task.getId(), task.getStatus(), task.getSendStartTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
} catch (JMSException e) {
jmsLogError(task);
}
// create SendTask and SendWorker for each Destination
for (Destination destination : task.getDestinations()) {
// submit for execution
SendTask sendTask = new SendTask(task, destination);
SendWorker worker = new SendWorkerImpl(sendTask, directory);
sendCompletionService.blockingSubmit(worker);
}
} catch (InterruptedException e) {
String errorStr = "Thread planning SendTasks was interrupted.";
log.error(errorStr);
throw new RuntimeException(errorStr, e);
} catch (Throwable ex) {
log.error("Unexpected exception in SendPlanner thread. Stuck Tasks will be cleaned by PropagationMaintainer#endStuckTasks() later.", ex);
}
}
}
use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.
the class BlockingGenExecutorCompletionService method blockingTake.
@Override
public Task blockingTake() throws InterruptedException, TaskExecutionException {
Future<Task> taskFuture = completionService.take();
try {
// .get() throws CancellationException if Task processing was cancelled from outside
Task task = taskFuture.get();
removeTaskFuture(taskFuture);
return task;
} catch (ExecutionException e) {
Task task = executingGenTasks.get(taskFuture);
removeTaskFuture(taskFuture);
Throwable cause = e.getCause();
if (cause instanceof TaskExecutionException) {
// GEN Task failed and related Task and results are part of this exception
throw (TaskExecutionException) cause;
} else {
// Unexpected exception during processing, pass stored Task if possible
if (task == null) {
log.error("We couldn't get Task for failed Future<Task>: {}", e);
throw new RuntimeException("We couldn't get Task for failed Future<Task>", e);
}
throw new TaskExecutionException(task, "Unexpected exception during GEN Task processing.", e);
}
} catch (CancellationException ex) {
// processing was cancelled
Task removedTask = executingGenTasks.get(taskFuture);
removeTaskFuture(taskFuture);
if (removedTask == null) {
log.error("Somebody manually removed Future<Task> from executingGenTasks or Task was null: {}", ex);
// we can't do anything about it
throw ex;
}
// make sure GenCollector always get related Task
throw new TaskExecutionException(removedTask, "Processing of Task was cancelled before completion.");
}
}
Aggregations