use of com.evolveum.midpoint.task.quartzimpl.cluster.ClusterStatusInformation in project midpoint by Evolveum.
the class ExecutionManager method stopSchedulersAndTasks.
public boolean stopSchedulersAndTasks(Collection<String> nodeIdentifiers, long timeToWait, OperationResult parentResult) {
OperationResult result = parentResult.createSubresult(this.getClass().getName() + ".stopSchedulersAndTasks");
result.addCollectionOfSerializablesAsParam("nodeList", nodeIdentifiers);
result.addParam("timeToWait", timeToWait);
LOGGER.info("Stopping schedulers and tasks on nodes: {}, waiting {} ms for task(s) shutdown.", nodeIdentifiers, timeToWait);
for (String nodeIdentifier : nodeIdentifiers) {
stopScheduler(nodeIdentifier, result);
}
ClusterStatusInformation csi = getClusterStatusInformation(true, false, result);
Set<ClusterStatusInformation.TaskInfo> taskInfoList = csi.getTasksOnNodes(nodeIdentifiers);
LOGGER.debug("{} task(s) found on nodes that are going down, stopping them.", taskInfoList.size());
Set<Task> tasks = new HashSet<>();
for (ClusterStatusInformation.TaskInfo taskInfo : taskInfoList) {
try {
tasks.add(taskManager.getTask(taskInfo.getOid(), result));
} catch (ObjectNotFoundException e) {
LoggingUtils.logException(LOGGER, "Task {} that was about to be stopped does not exist. Ignoring it.", e, taskInfo.getOid());
} catch (SchemaException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Task {} that was about to be stopped cannot be read due to schema problem. Ignoring it.", e, taskInfo.getOid());
}
}
boolean stopped = stopTasksRunAndWait(tasks, csi, timeToWait, true, result);
LOGGER.trace("All tasks stopped = " + stopped);
result.recordSuccessIfUnknown();
return stopped;
}
use of com.evolveum.midpoint.task.quartzimpl.cluster.ClusterStatusInformation in project midpoint by Evolveum.
the class ExecutionManager method waitForTaskRunCompletion.
// boolean stopTaskAndWait(Task task, long waitTime, boolean clusterwide) {
// ArrayList<Task> list = new ArrayList<Task>(1);
// list.add(task);
// return stopTasksRunAndWait(list, waitTime, clusterwide);
// }
// returns true if tasks are down
private boolean waitForTaskRunCompletion(Collection<Task> tasks, long maxWaitTime, boolean clusterwide, OperationResult parentResult) {
OperationResult result = parentResult.createSubresult(ExecutionManager.class.getName() + ".waitForTaskRunCompletion");
result.addArbitraryCollectionAsParam("tasks", tasks);
result.addParam("maxWaitTime", maxWaitTime);
result.addParam("clusterwide", clusterwide);
boolean interruptExecuted = false;
LOGGER.trace("Waiting for task(s) " + tasks + " to complete, at most for " + maxWaitTime + " ms.");
Set<String> oids = new HashSet<>();
for (Task t : tasks) if (t.getOid() != null)
oids.add(t.getOid());
long singleWait = WAIT_FOR_COMPLETION_INITIAL;
long started = System.currentTimeMillis();
for (; ; ) {
boolean isAnythingExecuting = false;
ClusterStatusInformation rtinfo = getClusterStatusInformation(clusterwide, false, result);
for (String oid : oids) {
if (rtinfo.findNodeInfoForTask(oid) != null) {
isAnythingExecuting = true;
break;
}
}
if (!isAnythingExecuting) {
String message = "The task(s), for which we have been waiting for, have finished.";
LOGGER.trace(message);
result.recordStatus(OperationResultStatus.SUCCESS, message);
return true;
}
if (maxWaitTime > 0 && System.currentTimeMillis() - started >= maxWaitTime) {
String message = "Wait time has elapsed without (some of) tasks being stopped. Finishing waiting for task(s) completion.";
LOGGER.trace(message);
result.recordWarning(message);
return false;
}
if (getConfiguration().getUseThreadInterrupt() == UseThreadInterrupt.WHEN_NECESSARY && !interruptExecuted && System.currentTimeMillis() - started >= INTERRUPT_TASK_THREAD_AFTER) {
LOGGER.info("Some tasks have not completed yet, sending their threads the 'interrupt' signal (if running locally).");
for (String oid : oids) {
localNodeManager.interruptLocalTaskThread(oid);
}
interruptExecuted = true;
}
LOGGER.trace("Some tasks have not completed yet, waiting for " + singleWait + " ms (max: " + maxWaitTime + ")");
try {
Thread.sleep(singleWait);
} catch (InterruptedException e) {
LOGGER.trace("Waiting interrupted" + e);
}
if (singleWait < WAIT_FOR_COMPLETION_MAX)
singleWait *= 2;
}
}
use of com.evolveum.midpoint.task.quartzimpl.cluster.ClusterStatusInformation in project midpoint by Evolveum.
the class ExecutionManager method getClusterStatusInformation.
/*
* ==================== NODE-LEVEL METHODS (QUERIES) ====================
*/
public ClusterStatusInformation getClusterStatusInformation(boolean clusterwide, boolean allowCached, OperationResult parentResult) {
OperationResult result = parentResult.createSubresult(ExecutionManager.class.getName() + ".getClusterStatusInformation");
result.addParam("clusterwide", clusterwide);
if (allowCached && clusterwide && lastClusterStatusInformation != null && lastClusterStatusInformation.isFresh(ALLOWED_CLUSTER_STATE_INFORMATION_AGE)) {
result.recordSuccess();
return lastClusterStatusInformation;
}
ClusterStatusInformation retval = new ClusterStatusInformation();
if (clusterwide) {
for (PrismObject<NodeType> node : taskManager.getClusterManager().getAllNodes(result)) {
addNodeAndTaskInformation(retval, node, result);
}
} else {
addNodeAndTaskInformation(retval, taskManager.getClusterManager().getNodePrism(), result);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("cluster state information = {}", retval.dump());
}
if (clusterwide) {
lastClusterStatusInformation = retval;
}
result.recomputeStatus();
return retval;
}
use of com.evolveum.midpoint.task.quartzimpl.cluster.ClusterStatusInformation in project midpoint by Evolveum.
the class JobExecutor method checkExecutionConstraints.
// returns false if constraints are not met (i.e. execution should finish immediately)
private boolean checkExecutionConstraints(TaskQuartzImpl task, JobExecutionContext context, OperationResult result) throws JobExecutionException {
TaskExecutionConstraintsType executionConstraints = task.getExecutionConstraints();
if (executionConstraints == null) {
return true;
}
// group limit
String group = executionConstraints.getGroup();
if (group != null) {
List<Task> tasksInGroup = new ArrayList<>();
ClusterStatusInformation clusterStatusInformation = taskManagerImpl.getExecutionManager().getClusterStatusInformation(true, false, result);
for (ClusterStatusInformation.TaskInfo taskInfo : clusterStatusInformation.getTasks()) {
Task runningTask;
try {
runningTask = taskManagerImpl.getTask(taskInfo.getOid(), result);
} catch (ObjectNotFoundException e) {
LOGGER.debug("Couldn't find running task {} when checking execution constraints: {}", taskInfo.getOid(), e.getMessage());
continue;
} catch (SchemaException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't retrieve running task {} when checking execution constraints", e, taskInfo.getOid());
continue;
}
if (group.equals(runningTask.getGroup()) && !task.getOid().equals(runningTask.getOid())) {
tasksInGroup.add(runningTask);
}
}
int limit = executionConstraints.getGroupTaskLimit() != null ? executionConstraints.getGroupTaskLimit() : 1;
LOGGER.trace("Tasks in group {}: {}", group, tasksInGroup);
if (tasksInGroup.size() >= limit) {
RescheduleTime rescheduleTime = getRescheduleTime(executionConstraints, DEFAULT_RESCHEDULE_TIME_FOR_GROUP_LIMIT, task.getNextRunStartTime(result));
LOGGER.info("Limit of {} task(s) in group {} would be exceeded if task {} would start. Existing tasks: {}." + " Will try again at {}{}.", limit, group, task, tasksInGroup, rescheduleTime.asDate(), rescheduleTime.regular ? " (i.e. at the next regular run time)" : "");
if (!rescheduleTime.regular) {
rescheduleLater(task, rescheduleTime.timestamp);
}
return false;
}
}
// node restrictions
String currentNode = taskManagerImpl.getNodeId();
List<String> allowedNodes = executionConstraints.getAllowedNode();
List<String> disallowedNodes = executionConstraints.getDisallowedNode();
if (!passesAllowed(currentNode, allowedNodes)) {
rescheduleToAllowedNode(task, "is not among allowed nodes (" + allowedNodes + ")", allowedNodes, disallowedNodes, context, result);
return false;
}
if (!passesDisallowed(currentNode, disallowedNodes)) {
rescheduleToAllowedNode(task, "is among disallowed nodes (" + disallowedNodes + ")", allowedNodes, disallowedNodes, context, result);
return false;
}
return true;
}
use of com.evolveum.midpoint.task.quartzimpl.cluster.ClusterStatusInformation in project midpoint by Evolveum.
the class JobExecutor method getAvailableNode.
private NodeType getAvailableNode(List<String> allowedNodes, List<String> disallowedNodes, OperationResult result) {
ClusterStatusInformation clusterStatusInformation = taskManagerImpl.getExecutionManager().getClusterStatusInformation(true, false, result);
List<NodeType> matching = clusterStatusInformation.getNodes().stream().filter(node -> passes(node.getNodeIdentifier(), allowedNodes, disallowedNodes) && node.getExecutionStatus() == NodeExecutionStatusType.RUNNING).collect(Collectors.toList());
if (matching.isEmpty()) {
return null;
} else {
return matching.get((int) (Math.random() * matching.size()));
}
}
Aggregations