com.atlassian.bamboo.specs.util.IsolatedExecutor Maven / Gradle / Ivy
package com.atlassian.bamboo.specs.util;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.function.Function;
public final class IsolatedExecutor {
private final BlockingQueue inputQueue = new SynchronousQueue<>();
private final BlockingQueue> resultQueue = new SynchronousQueue<>();
private final Thread executionThread;
public Thread getThread() {
return executionThread;
}
private static final class Either {
private final R result;
private final Throwable exception;
private Either(final R result, final Throwable exception) {
this.result = result;
this.exception = exception;
}
private static Either right(final R result) {
return new Either<>(result, null);
}
private static Either left(final Throwable e) {
return new Either<>(null, e);
}
public R get() throws Throwable {
if (exception!=null) {
throw exception;
} else {
return result;
}
}
}
public IsolatedExecutor(final Function inputProcessor, final String name) {
executionThread = new Thread(name) {
@Override
public void run() {
while (true) {
final T input = take(inputQueue);
try {
putResult(Either.right(inputProcessor.apply(input)));
} catch (final Throwable e) {
putResult(Either.left(e));
}
}
}
};
executionThread.setDaemon(true);
}
public void start() {
executionThread.start();
}
private T take(final BlockingQueue queue) {
try {
return queue.take();
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
private void putResult(final Either result) {
try {
resultQueue.put(result);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
public R execute(final T task) throws Throwable {
try {
inputQueue.put(task);
return resultQueue.take().get();
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
}