com.softicar.platform.common.core.thread.function.ParallelFunctionRunner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of platform-common Show documentation
Show all versions of platform-common Show documentation
The SoftiCAR Platform is a lightweight, Java-based library to create interactive business web applications.
package com.softicar.platform.common.core.thread.function;
import com.softicar.platform.common.core.thread.collection.ThreadCollection;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class ParallelFunctionRunner {
private final Function function;
private final Map inputValues;
private final Map exceptions;
private BiConsumer resultConsumer;
private BiConsumer exceptionConsumer;
private long millisPerTry;
private long tryCount;
public ParallelFunctionRunner(Function function) {
this.function = function;
this.inputValues = new TreeMap<>();
this.exceptions = new TreeMap<>();
}
public ParallelFunctionRunner addInputValue(T values) {
this.inputValues.put(inputValues.size(), values);
return this;
}
public ParallelFunctionRunner addInputValues(Collection values) {
values.stream().forEach(this::addInputValue);
return this;
}
public ParallelFunctionRunner setResultConsumer(BiConsumer consumer) {
this.resultConsumer = consumer;
return this;
}
public ParallelFunctionRunner setExceptionConsumer(BiConsumer exceptionConsumer) {
this.exceptionConsumer = exceptionConsumer;
return this;
}
public ParallelFunctionRunner setMillisPerTry(long millisPerTry) {
this.millisPerTry = millisPerTry;
return this;
}
public ParallelFunctionRunner setTryCount(long tryCount) {
this.tryCount = tryCount;
return this;
}
public void apply() {
if (resultConsumer == null) {
throw new IllegalStateException("No result consumer defined.");
}
for (int i = 0; i < tryCount && !inputValues.isEmpty(); i++) {
// create function threads
Map> threads = new TreeMap<>();
for (Entry entry: inputValues.entrySet()) {
threads.put(entry.getKey(), new FunctionThread<>(function, entry.getValue()));
}
// run function threads
new ThreadCollection<>(threads.values()).runAll(millisPerTry);
// get result values from function threads
for (Entry> entry: threads.entrySet()) {
Integer index = entry.getKey();
FunctionThread thread = entry.getValue();
if (thread.getException() == null) {
resultConsumer.accept(thread.getInput(), thread.getResult());
inputValues.remove(index);
exceptions.remove(index);
} else {
exceptions.put(index, thread.getException());
}
}
}
// provide exceptions if wanted
if (exceptionConsumer != null) {
for (Entry entry: exceptions.entrySet()) {
T inputValue = inputValues.get(entry.getKey());
exceptionConsumer.accept(inputValue, entry.getValue());
}
}
}
public Exception getException(T key) {
return exceptions.get(key);
}
}