io.convergence_platform.common.tasks.TaskExecutionEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of service-lib Show documentation
Show all versions of service-lib Show documentation
Holds the common functionality needed by all Convergence Platform-based services written in Java.
The newest version!
package io.convergence_platform.common.tasks;
import io.convergence_platform.common.dag.DirectedAcyclicGraph;
import java.util.*;
public class TaskExecutionEngine extends DirectedAcyclicGraph {
private final int threadCount;
private final Map sharedMemory = new HashMap<>();
private List tasks = new ArrayList<>();
public TaskExecutionEngine() {
this(4);
}
public TaskExecutionEngine(int threadCount) {
this.threadCount = threadCount;
}
public void addTask(SubTask task) {
tasks.add(task);
}
public List getSortedTasks() {
initialize(tasks);
return topologicalSort();
}
public void setSharedMemoryValue(String name, Object value) {
synchronized (sharedMemory) {
sharedMemory.put(name, value);
}
}
public Object getSharedMemoryValue(String name) {
Object result = null;
synchronized (sharedMemory) {
result = sharedMemory.get(name);
}
return result;
}
public boolean execute() {
validate();
initialize(tasks);
List executionOrder = topologicalSort();
Set finishedTasks = new HashSet<>();
Set failedTasks = new HashSet<>();
List threads = createEngineThreads(executionOrder, finishedTasks, failedTasks);
while (shouldWait(threads, failedTasks, finishedTasks)) {
waitFor(500);
}
markThreadsAsFinished(threads);
waitUntilAllThreadsFinish(threads);
return failedTasks.size() == 0 && finishedTasks.size() == tasks.size();
}
private void validate() {
validateAllDependenciesInTaskList();
}
private void validateAllDependenciesInTaskList() {
Set allTasks = new HashSet<>();
for (SubTask t : tasks) {
allTasks.add(t);
allTasks.addAll(t.getDependencies());
}
if (!new HashSet<>(tasks).containsAll(allTasks)) {
throw new RuntimeException("All task dependencies should be added to the DAG engine.");
}
}
private void markThreadsAsFinished(List threads) {
for (TaskExecutionEngineThread t : threads) {
t.markFinished();
}
}
private void waitUntilAllThreadsFinish(List threads) {
boolean allTerminated = false;
long endTime = System.currentTimeMillis() + 1000 * 60 * 5;
while (!allTerminated && System.currentTimeMillis() < endTime) {
allTerminated = true;
for (TaskExecutionEngineThread t : threads) {
allTerminated = allTerminated && t.isThreadTerminated();
}
if (!allTerminated) {
waitFor(1000);
}
}
}
private void waitFor(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
}
}
private boolean shouldWait(List threads, Set failedTasks, Set finishedTasks) {
if (failedTasks.size() != 0) return false;
return finishedTasks.size() != tasks.size();
}
private List createEngineThreads(List executionOrder, Set finishedTasks, Set failedTasks) {
List result = new ArrayList<>();
for (int i = 0; i < threadCount; i++) {
TaskExecutionEngineThread thread = new TaskExecutionEngineThread(executionOrder, finishedTasks, failedTasks);
thread.start();
result.add(thread);
}
return result;
}
}