Search in sources :

Example 1 with CoordJobGetReadyActionsJPAExecutor

use of org.apache.oozie.executor.jpa.CoordJobGetReadyActionsJPAExecutor in project oozie by apache.

the class CoordActionReadyXCommand method execute.

@Override
protected /**
 * Check for READY actions and change state to SUBMITTED by a command to submit the job to WF engine.
 * This method checks all the actions associated with a jobId to figure out which actions
 * to start (based on concurrency and execution order [FIFO, LIFO, LAST_ONLY, NONE])
 */
Void execute() throws CommandException {
    // number of actions to start (-1 means start ALL)
    int numActionsToStart = -1;
    // get execution setting for this job (FIFO, LIFO, LAST_ONLY)
    CoordinatorJob.Execution jobExecution = coordJob.getExecutionOrder();
    // get concurrency setting for this job
    int jobConcurrency = coordJob.getConcurrency();
    // if less than 0, then UNLIMITED concurrency
    if (jobConcurrency >= 0) {
        // count number of actions that are already RUNNING or SUBMITTED
        // subtract from CONCURRENCY to calculate number of actions to start
        // in WF engine
        int numRunningJobs;
        try {
            numRunningJobs = jpaService.execute(new CoordJobGetRunningActionsCountJPAExecutor(jobId));
        } catch (JPAExecutorException je) {
            throw new CommandException(je);
        }
        numActionsToStart = jobConcurrency - numRunningJobs;
        if (numActionsToStart < 0) {
            numActionsToStart = 0;
        }
        log.debug("concurrency=" + jobConcurrency + ", execution=" + jobExecution + ", numRunningJobs=" + numRunningJobs + ", numLeftover=" + numActionsToStart);
        // no actions to start
        if (numActionsToStart == 0) {
            log.info("Not starting any additional actions because max concurrency [{0}]" + " for coordinator [{1}] has been reached.", jobConcurrency, jobId);
        }
    }
    // get list of actions that are READY and fit in the concurrency and execution
    List<CoordinatorActionBean> actions;
    try {
        actions = jpaService.execute(new CoordJobGetReadyActionsJPAExecutor(jobId, jobExecution.name()));
    } catch (JPAExecutorException je) {
        throw new CommandException(je);
    }
    log.debug("Number of READY actions = " + actions.size());
    Date now = new Date();
    // If we're using LAST_ONLY or NONE, we should check if any of these need to be SKIPPED instead of SUBMITTED
    if (jobExecution.equals(CoordinatorJobBean.Execution.LAST_ONLY)) {
        for (Iterator<CoordinatorActionBean> it = actions.iterator(); it.hasNext(); ) {
            CoordinatorActionBean action = it.next();
            try {
                Date nextNominalTime = CoordCommandUtils.computeNextNominalTime(coordJob, action);
                if (nextNominalTime != null) {
                    // action should be started; so set it to SKIPPED
                    if (now.after(nextNominalTime)) {
                        LOG.info("LAST_ONLY execution: Preparing to skip action [{0}] because the current time [{1}] is later " + "than the nominal time [{2}] of the next action]", action.getId(), DateUtils.formatDateOozieTZ(now), DateUtils.formatDateOozieTZ(nextNominalTime));
                        queue(new CoordActionSkipXCommand(action, coordJob.getUser(), coordJob.getAppName()));
                        it.remove();
                    } else {
                        LOG.debug("LAST_ONLY execution: Not skipping action [{0}] because the current time [{1}] is earlier " + "than the nominal time [{2}] of the next action]", action.getId(), DateUtils.formatDateOozieTZ(now), DateUtils.formatDateOozieTZ(nextNominalTime));
                    }
                }
            } catch (ParseException e) {
                LOG.error("Should not happen", e);
            } catch (JDOMException e) {
                LOG.error("Should not happen", e);
            }
        }
    } else if (jobExecution.equals(CoordinatorJobBean.Execution.NONE)) {
        for (Iterator<CoordinatorActionBean> it = actions.iterator(); it.hasNext(); ) {
            CoordinatorActionBean action = it.next();
            // If the current time is after the nominal time of this action plus some tolerance,
            // then we've passed the window where this action should be started; so set it to SKIPPED
            Calendar cal = Calendar.getInstance(DateUtils.getTimeZone(coordJob.getTimeZone()));
            cal.setTime(action.getNominalTime());
            int tolerance = ConfigurationService.getInt(CoordActionInputCheckXCommand.COORD_EXECUTION_NONE_TOLERANCE);
            cal.add(Calendar.MINUTE, tolerance);
            if (now.after(cal.getTime())) {
                LOG.info("NONE execution: Preparing to skip action [{0}] because the current time [{1}] is more than [{2}]" + " minutes later than the nominal time [{3}] of the current action]", action.getId(), DateUtils.formatDateOozieTZ(now), tolerance, DateUtils.formatDateOozieTZ(action.getNominalTime()));
                queue(new CoordActionSkipXCommand(action, coordJob.getUser(), coordJob.getAppName()));
                it.remove();
            } else {
                LOG.debug("NONE execution: Not skipping action [{0}] because the current time [{1}] is earlier than [{2}]" + " minutes later than the nominal time [{3}] of the current action]", action.getId(), DateUtils.formatDateOozieTZ(now), tolerance, DateUtils.formatDateOozieTZ(action.getNominalTime()));
            }
        }
    }
    int counter = 0;
    for (CoordinatorActionBean action : actions) {
        // actions), or if the counter is less than numActionsToStart
        if ((numActionsToStart < 0) || (counter < numActionsToStart)) {
            log.debug("Set status to SUBMITTED for id: " + action.getId());
            // change state of action to SUBMITTED
            action.setStatus(CoordinatorAction.Status.SUBMITTED);
            try {
                CoordActionQueryExecutor.getInstance().executeUpdate(CoordActionQuery.UPDATE_COORD_ACTION_STATUS_PENDING_TIME, action);
            } catch (JPAExecutorException je) {
                throw new CommandException(je);
            }
            // start action
            new CoordActionStartXCommand(action.getId(), coordJob.getUser(), coordJob.getAppName(), action.getJobId()).call();
        } else {
            break;
        }
        counter++;
    }
    return null;
}
Also used : CoordinatorActionBean(org.apache.oozie.CoordinatorActionBean) Calendar(java.util.Calendar) CoordJobGetReadyActionsJPAExecutor(org.apache.oozie.executor.jpa.CoordJobGetReadyActionsJPAExecutor) CommandException(org.apache.oozie.command.CommandException) JDOMException(org.jdom.JDOMException) Date(java.util.Date) CoordinatorJob(org.apache.oozie.client.CoordinatorJob) JPAExecutorException(org.apache.oozie.executor.jpa.JPAExecutorException) Iterator(java.util.Iterator) CoordJobGetRunningActionsCountJPAExecutor(org.apache.oozie.executor.jpa.CoordJobGetRunningActionsCountJPAExecutor) ParseException(java.text.ParseException)

Aggregations

ParseException (java.text.ParseException)1 Calendar (java.util.Calendar)1 Date (java.util.Date)1 Iterator (java.util.Iterator)1 CoordinatorActionBean (org.apache.oozie.CoordinatorActionBean)1 CoordinatorJob (org.apache.oozie.client.CoordinatorJob)1 CommandException (org.apache.oozie.command.CommandException)1 CoordJobGetReadyActionsJPAExecutor (org.apache.oozie.executor.jpa.CoordJobGetReadyActionsJPAExecutor)1 CoordJobGetRunningActionsCountJPAExecutor (org.apache.oozie.executor.jpa.CoordJobGetRunningActionsCountJPAExecutor)1 JPAExecutorException (org.apache.oozie.executor.jpa.JPAExecutorException)1 JDOMException (org.jdom.JDOMException)1