org.conqat.lib.commons.concurrent.TaskWrappingExecutorService Maven / Gradle / Ivy
Show all versions of teamscale-lib-commons Show documentation
package org.conqat.lib.commons.concurrent;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.conqat.lib.commons.assertion.CCSMAssert;
/**
* {@link ExecutorService} wrapping every submitted task ({@link Runnable} or {@link Callable}) with
* a provided {@link Wrapper}.
*
* This can be useful if e.g. a special pre- or post-operation should be performed for every task
* (in the submitting or the executing thread).
*/
public class TaskWrappingExecutorService implements ExecutorService {
private final ExecutorService delegate;
private final Wrapper taskWrapper;
public TaskWrappingExecutorService(ExecutorService delegate, Wrapper taskWrapper) {
CCSMAssert.isNotNull(delegate, () -> String.format("Expected \"%s\" to be not null", "delegate"));
CCSMAssert.isNotNull(taskWrapper, () -> String.format("Expected \"%s\" to be not null", "taskWrapper"));
this.delegate = delegate;
this.taskWrapper = taskWrapper;
}
@Override
public void shutdown() {
delegate.shutdown();
}
@NonNull
@Override
public List shutdownNow() {
return delegate.shutdownNow().stream().map(taskWrapper::unwrap).collect(Collectors.toList());
}
@Override
public boolean isShutdown() {
return delegate.isShutdown();
}
@Override
public boolean isTerminated() {
return delegate.isTerminated();
}
@Override
public boolean awaitTermination(long timeout, @NonNull TimeUnit unit) throws InterruptedException {
return delegate.awaitTermination(timeout, unit);
}
@NonNull
@Override
public Future submit(@NonNull Callable task) {
return delegate.submit(taskWrapper.wrap(task));
}
@NonNull
@Override
public Future submit(@NonNull Runnable task, T result) {
return delegate.submit(taskWrapper.wrap(task), result);
}
@NonNull
@Override
public Future submit(@NonNull Runnable task) {
return delegate.submit(taskWrapper.wrap(task));
}
@NonNull
@Override
public List> invokeAll(@NonNull Collection> tasks) throws InterruptedException {
return delegate.invokeAll(wrap(tasks));
}
@NonNull
@Override
public List> invokeAll(@NonNull Collection> tasks, long timeout,
@NonNull TimeUnit unit) throws InterruptedException {
return delegate.invokeAll(wrap(tasks), timeout, unit);
}
@NonNull
@Override
public T invokeAny(@NonNull Collection> tasks)
throws InterruptedException, ExecutionException {
return delegate.invokeAny(wrap(tasks));
}
@Override
public T invokeAny(@NonNull Collection> tasks, long timeout, @NonNull TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return delegate.invokeAny(wrap(tasks), timeout, unit);
}
@NonNull
private List> wrap(@NonNull Collection> tasks) {
return tasks.stream().map(taskWrapper::wrap).collect(Collectors.toList());
}
@Override
public void execute(@NonNull Runnable command) {
delegate.execute(taskWrapper.wrap(command));
}
/**
* Provides functionality to wrap and unwrap submitted tasks.
*/
public interface Wrapper {
/**
* Wraps and returns the provided {@code callable} in a new {@link Callable} with the desired
* behaviour.
*/
@NonNull Callable wrap(@NonNull Callable callable);
/**
* Retrieves the original {@link Callable} from the {@link #wrap(Callable) wrapped}
* {@code callable}.
*/
@NonNull Callable unwrap(@NonNull Callable callable);
/**
* Wraps and returns the provided {@code runnable} in a new {@link Runnable} with the desired
* behaviour.
*/
@NonNull
Runnable wrap(@NonNull Runnable runnable);
/**
* Retrieves the original {@link Runnable} from the {@link #wrap(Runnable) wrapped}
* {@code runnable}.
*/
@NonNull
Runnable unwrap(@NonNull Runnable runnable);
}
}