/** Returns a list of {@code Execution}s that are still not complete for a given actionInstance */ private List<Execution> getInCompleteExecutionsBefore( String actionInstanceId, Execution currentExecution) { List<Execution> executions = executionDao.getExecutions(actionInstanceId); List<Execution> incomplete = new ArrayList<>(); for (Execution execution : executions) { if (execution.isBefore(currentExecution) && !currentExecution.getId().equals(execution.getId()) && (execution.getStatus() == null || !execution.getStatus().isComplete())) { incomplete.add(execution); } } return incomplete; }
/** * Cancels the currently running {@code Execution} for given {@code ActionInstance} id * * @throws ActionInstanceNotFoundException */ @Override public void cancel(String executionId) throws ExecutionNotFoundException, ActionInstanceNotFoundException { Execution execution = executionDao.getExecution(executionId); if (execution != null) { ActionInstance actionInstance = actionInstanceDao.getActionInstance(execution.getActionInstanceId()); if (actionInstance != null) { cancel(execution, actionInstance); } else { throw new ExecutionNotFoundException( String.format("No actionInstance found associated with executionId: %s", executionId)); } } else { throw new ActionInstanceNotFoundException( String.format("No execution found for executionId: %s", executionId)); } }
protected void cancelLocal(final Execution execution, final ActionInstance actionInstance) { Execution updatedExecution = executionDao.getExecution(execution.getId()); Status status = updatedExecution.getStatus(); if (status != null && status.isComplete()) { return; } cancelService.submit( new Runnable() { @Override public void run() { try { Action action = actionInstance.getAction().newInstance(); executor.cancel(action, actionInstance, execution); logger.info("Cancelled action {} for execution {}", action, execution); } catch (InstantiationException | IllegalAccessException e) { Status status = Status.FAILED; status.setMessage( String.format( "Exception occurred while creating an action instance of type %s: %s", actionInstance.getAction(), e.getMessage())); execution.setEndTime(new Date()); execution.setStatus(status); } catch (ExecutionException e) { Status status = e.getStatus() != null ? e.getStatus() : Status.FAILED; status.setMessage(e.getMessage()); execution.setEndTime(new Date()); execution.setStatus(status); } catch (Exception e) { Status status = Status.FAILED; status.setMessage( String.format( "Exception occurred while cancelling execution %s: %s", execution, e.getMessage())); execution.setEndTime(new Date()); execution.setStatus(status); } finally { executionDao.updateExecution(execution); } } }); }
/** * Executes the {@code ActionInstance} * * @throws com.netflix.scheduledactions.exceptions.ExecutionException */ public Execution execute(final ActionInstance actionInstance, String initiator) { if (actionInstance.isDisabled()) { return null; } final String actionInstanceId = actionInstance.getId(); final Execution execution = new Execution(delegateId, actionInstanceId); final String executionId = executionDao.createExecution(actionInstanceId, execution); logger.info("[{}] Created execution for actionInstance: {}", actionInstanceId, executionId); execution.getLogger().info(String.format("Created execution %s", executionId)); List<Execution> previousExecutions = getInCompleteExecutionsBefore(actionInstanceId, execution); if (previousExecutions.size() > 0) { ConcurrentExecutionStrategy strategy = actionInstance.getConcurrentExecutionStrategy(); switch (strategy) { case ALLOW: execution .getLogger() .info("Concurrent execution strategy is: ALLOW, allowing execution..."); logger.info( "[{}] actionInstance concurrent execution strategy is: ALLOW, allowing execution...", actionInstanceId); break; case REJECT: Status status = Status.SKIPPED; status.setMessage( String.format( "ConcurrentExecutionStrategy for ActionInstance %s is REJECT and it has incomplete executions", actionInstance)); execution.setStatus(status); execution.setStartTime(new Date()); execution.setEndTime(new Date()); logger.info( "[{}] actionInstance concurrent execution strategy is: REJECT, skipping execution", actionInstanceId); execution .getLogger() .info("Concurrent execution strategy is: REJECT, skipping execution"); executionDao.updateExecution(execution); return execution; case REPLACE: logger.info( "[{}] actionInstance concurrent execution strategy is: REPLACE, cancelling previous execution(s)", actionInstanceId); cancelPreviousExecutions(actionInstance, execution); break; default: break; } } logger.info("[{}] Submitting runnable for execution: {}", actionInstanceId, executionId); executeService.submit( new Runnable() { @Override public void run() { try { Action action = newInstance(actionInstance); execution.getLogger().info("Calling executor.execute()..."); logger.info( "[{}] Calling executor.execute() for execution {} ...", actionInstanceId, executionId); executor.execute(action, actionInstance, execution); } catch (ExecutionException e) { Status status = e.getStatus() != null ? e.getStatus() : Status.FAILED; status.setMessage(e.getMessage()); execution.setEndTime(new Date()); execution.setStatus(status); execution.getLogger().error("Exception occurred while executing action", e); } catch (Exception e) { Status status = Status.FAILED; status.setMessage( String.format( "Exception occurred while executing action %s: %s", actionInstance.getAction(), e.getMessage())); execution.getLogger().error("Exception occurred while executing action", e); execution.setEndTime(new Date()); execution.setStatus(status); } finally { executionDao.updateExecution(execution); } } }); return execution; }