Search in sources :

Example 1 with TaskSchedule

use of cz.metacentrum.perun.taskslib.model.TaskSchedule in project perun by CESNET.

the class TaskScheduler method run.

// ----- methods -------------------------------------
/**
 * This method runs in separate thread perpetually trying to take tasks from delay queue, blocking if none are available.
 * If there is Task ready, we check if it source was updated. If it was, we put the task back to the queue (This
 * can happen only limited number of times). If on the other hand it was not updated we perform additional checks using
 * method sendToEngine.
 */
@Override
public void run() {
    try {
        initPerunSession();
    } catch (InternalErrorException e1) {
        String message = "Dispatcher was unable to initialize Perun session.";
        log.error(message, e1);
        throw new RuntimeException(message, e1);
    }
    log.debug("Pool contains {} tasks in total", schedulingPool.getSize());
    TaskSchedule schedule;
    while (!shouldStop()) {
        try {
            if (tasksManagerBl.isSuspendedTasksPropagation()) {
                // do not continue sending tasks to the engine until propagation is set to resume
                waitForResumingPropagation();
            }
            schedule = getWaitingTaskSchedule();
        } catch (InterruptedException e) {
            String message = "Thread was interrupted, cannot continue.";
            log.error(message, e);
            throw new RuntimeException(message, e);
        }
        Task task = schedule.getTask();
        if (task.isSourceUpdated() && schedule.getDelayCount() > 0 && !task.isPropagationForced()) {
            // source data changed before sending, wait for more changes to come -> reschedule
            log.warn("[{}] Task was not allowed to be sent to Engine now: {}.", task.getId(), task);
            schedulingPool.scheduleTask(task, schedule.getDelayCount() - 1);
        } else {
            // send it to engine
            TaskScheduled reason = sendToEngine(task);
            switch(reason) {
                case QUEUE_ERROR:
                    log.warn("[{}] Task dispatcherQueue could not be set, so it is rescheduled: {}.", task.getId(), task);
                    schedulingPool.scheduleTask(task, -1);
                    break;
                case DENIED:
                    // Task is lost from waiting queue, since somebody blocked service on facility, all destinations or globally
                    log.info("[{}] Execution was denied for Task before sending to Engine: {}.", task.getId(), task);
                    break;
                case ERROR:
                    log.error("[{}] Unexpected error when scheduling Task, so it is rescheduled: {}.", task.getId(), task);
                    schedulingPool.scheduleTask(task, -1);
                    break;
                case SUCCESS:
                    log.info("[{}] Task was successfully sent to Engine: {}.", task.getId(), task);
                    break;
                case DB_ERROR:
                    // Task is lost from waiting queue, will be cleared from pool by propagation maintainer
                    log.warn("[{}] Facility, Service or Destination could not be found in DB for Task {}.", task.getId(), task);
                    break;
            }
            // update task status in DB
            tasksManagerBl.updateTask(perunSession, task);
        }
    }
    log.debug("TaskScheduler has stopped.");
}
Also used : Task(cz.metacentrum.perun.taskslib.model.Task) TaskScheduled(cz.metacentrum.perun.dispatcher.scheduling.impl.TaskScheduled) TaskSchedule(cz.metacentrum.perun.taskslib.model.TaskSchedule) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException)

Example 2 with TaskSchedule

use of cz.metacentrum.perun.taskslib.model.TaskSchedule in project perun by CESNET.

the class SchedulingPoolImpl method scheduleTask.

@Override
public void scheduleTask(Task task, int delayCount) {
    // check if service/facility exists
    boolean removeTask = false;
    try {
        Service service = perun.getServicesManager().getServiceById(sess, task.getServiceId());
        Facility facility = perun.getFacilitiesManager().getFacilityById(sess, task.getFacilityId());
        task.setService(service);
        task.setFacility(facility);
    } catch (ServiceNotExistsException e) {
        log.error("[{}] Task NOT added to waiting queue, service not exists: {}.", task.getId(), task);
        removeTask = true;
    } catch (FacilityNotExistsException e) {
        log.error("[{}] Task NOT added to waiting queue, facility not exists: {}.", task.getId(), task);
        removeTask = true;
    } catch (InternalErrorException | PrivilegeException e) {
        log.error("[{}] {}", task.getId(), e);
    }
    if (!task.getService().isEnabled() || ((PerunBl) perun).getServicesManagerBl().isServiceBlockedOnFacility(task.getService(), task.getFacility())) {
        log.error("[{}] Task NOT added to waiting queue, service is blocked: {}.", task.getId(), task);
        // do not change Task status or any other data !
        if (!removeTask)
            return;
    }
    try {
        List<Destination> destinations = perun.getServicesManager().getDestinations(sess, task.getService(), task.getFacility());
        if (destinations != null && !destinations.isEmpty()) {
            Iterator<Destination> iter = destinations.iterator();
            while (iter.hasNext()) {
                Destination dest = iter.next();
                if (((PerunBl) perun).getServicesManagerBl().isServiceBlockedOnDestination(task.getService(), 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("[{}] Task NOT added to waiting queue, all its destinations are blocked.", task.getId());
                if (!removeTask)
                    return;
            }
        }
    } catch (ServiceNotExistsException e) {
        log.error("[{}] Task NOT added to waiting queue, service not exists: {}.", task.getId(), task);
        removeTask = true;
    } catch (FacilityNotExistsException e) {
        log.error("[{}] Task NOT added to waiting queue, facility not exists: {}.", task.getId(), task);
        removeTask = true;
    } catch (InternalErrorException | PrivilegeException e) {
        log.error("[{}] {}", task.getId(), e);
    }
    try {
        List<Service> assignedServices = perun.getServicesManager().getAssignedServices(sess, task.getFacility());
        if (!assignedServices.contains(task.getService())) {
            log.debug("[{}] Task NOT added to waiting queue, service is not assigned to facility any more: {}.", task.getId(), task);
            if (!removeTask)
                return;
        }
    } catch (FacilityNotExistsException e) {
        removeTask = true;
        log.error("[{}] Task removed from database, facility no longer exists: {}.", task.getId(), task);
    } catch (InternalErrorException | PrivilegeException e) {
        log.error("[{}] Unable to check Service assignment to Facility: {}", task.getId(), e.getMessage());
    }
    if (removeTask) {
        // in memory task belongs to non existent facility/service - remove it and return
        try {
            removeTask(task);
            return;
        } catch (TaskStoreException e) {
            log.error("[{}] Unable to remove Task from pool: {}.", task.getId(), e);
            return;
        }
    }
    // Task is eligible for running - create new schedule
    task.setSourceUpdated(false);
    long newTaskDelay = 0;
    if (!task.isPropagationForced()) {
        // normal tasks are delayed
        try {
            newTaskDelay = Long.parseLong(dispatcherProperties.getProperty("dispatcher.task.delay.time"));
        } catch (NumberFormatException e) {
            log.warn("Could not parse value of dispatcher.task.delay.time property. Using default.");
            newTaskDelay = 30000;
        }
    }
    if (task.isPropagationForced()) {
        delayCount = 0;
    }
    if (delayCount < 0) {
        try {
            delayCount = Integer.parseInt(dispatcherProperties.getProperty("dispatcher.task.delay.count"));
        } catch (NumberFormatException e) {
            log.warn("Could not parse value of dispatcher.task.delay.count property. Using default.");
            delayCount = 4;
        }
    }
    TaskSchedule schedule = new TaskSchedule(newTaskDelay, task);
    schedule.setBase(System.currentTimeMillis());
    schedule.setDelayCount(delayCount);
    // Task was newly planned for propagation, switch state.
    if (!task.getStatus().equals(TaskStatus.WAITING)) {
        task.setStatus(TaskStatus.WAITING);
        task.setSchedule(LocalDateTime.now());
        // clear previous timestamps
        task.setSentToEngine((LocalDateTime) null);
        task.setStartTime((LocalDateTime) null);
        task.setGenStartTime((LocalDateTime) null);
        task.setSendStartTime((LocalDateTime) null);
        task.setEndTime((LocalDateTime) null);
        task.setGenEndTime((LocalDateTime) null);
        task.setSendEndTime((LocalDateTime) null);
        tasksManagerBl.updateTask(sess, task);
    }
    boolean added = false;
    if (schedule.getTask().isPropagationForced()) {
        added = waitingForcedTasksQueue.add(schedule);
    } else {
        added = waitingTasksQueue.add(schedule);
    }
    if (!added) {
        log.error("[{}] Task could not be added to waiting queue. Shouldn't ever happen. Look to javadoc of DelayQueue. {}", task.getId(), schedule);
    } else {
        log.debug("[{}] Task was added to waiting queue: {}", task.getId(), schedule);
    }
}
Also used : Destination(cz.metacentrum.perun.core.api.Destination) Service(cz.metacentrum.perun.core.api.Service) PerunBl(cz.metacentrum.perun.core.bl.PerunBl) FacilityNotExistsException(cz.metacentrum.perun.core.api.exceptions.FacilityNotExistsException) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) TaskStoreException(cz.metacentrum.perun.taskslib.exceptions.TaskStoreException) ServiceNotExistsException(cz.metacentrum.perun.core.api.exceptions.ServiceNotExistsException) TaskSchedule(cz.metacentrum.perun.taskslib.model.TaskSchedule) PrivilegeException(cz.metacentrum.perun.core.api.exceptions.PrivilegeException) Facility(cz.metacentrum.perun.core.api.Facility)

Example 3 with TaskSchedule

use of cz.metacentrum.perun.taskslib.model.TaskSchedule in project perun by CESNET.

the class TaskScheduler method getWaitingTaskSchedule.

/**
 * Internal method which chooses next Task that will be processed, we try to take forced Task first,
 * and if none is available, then we wait for a normal Task for a few seconds.
 *
 * @return Once one of the Queues returns non null TaskSchedule, we return it.
 * @throws InterruptedException When blocking queue polling was interrupted.
 */
private TaskSchedule getWaitingTaskSchedule() throws InterruptedException {
    TaskSchedule taskSchedule = null;
    while (!shouldStop()) {
        log.debug(schedulingPool.getReport());
        log.debug("WaitingTasksQueue has {} normal Tasks and {} forced Tasks.", waitingTasksQueue.size(), waitingForcedTasksQueue.size());
        taskSchedule = waitingForcedTasksQueue.poll();
        if (taskSchedule == null) {
            taskSchedule = waitingTasksQueue.poll(10, TimeUnit.SECONDS);
        }
        if (taskSchedule != null) {
            break;
        }
    }
    log.trace("[{}] Returning Task schedule {}.", taskSchedule.getTask().getId(), taskSchedule);
    return taskSchedule;
}
Also used : TaskSchedule(cz.metacentrum.perun.taskslib.model.TaskSchedule)

Aggregations

TaskSchedule (cz.metacentrum.perun.taskslib.model.TaskSchedule)3 InternalErrorException (cz.metacentrum.perun.core.api.exceptions.InternalErrorException)2 Destination (cz.metacentrum.perun.core.api.Destination)1 Facility (cz.metacentrum.perun.core.api.Facility)1 Service (cz.metacentrum.perun.core.api.Service)1 FacilityNotExistsException (cz.metacentrum.perun.core.api.exceptions.FacilityNotExistsException)1 PrivilegeException (cz.metacentrum.perun.core.api.exceptions.PrivilegeException)1 ServiceNotExistsException (cz.metacentrum.perun.core.api.exceptions.ServiceNotExistsException)1 PerunBl (cz.metacentrum.perun.core.bl.PerunBl)1 TaskScheduled (cz.metacentrum.perun.dispatcher.scheduling.impl.TaskScheduled)1 TaskStoreException (cz.metacentrum.perun.taskslib.exceptions.TaskStoreException)1 Task (cz.metacentrum.perun.taskslib.model.Task)1