package tc.oc.commons.core.concurrent;
import java.util.concurrent.Callable;
import javax.annotation.Nullable;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.SettableFuture;
import tc.oc.commons.core.util.StackTrace;
import tc.oc.commons.core.util.ThrowingRunnable;
import tc.oc.commons.core.util.Traceables;
public interface CatchingExecutorService extends CatchingExecutor, ListeningExecutorService {
default <T> ListenableFuture<T> submit(Callable<T> task, @Nullable StackTrace source) {
final SettableFuture<T> future = SettableFuture.create();
executeCatch(() -> {
final T result;
try {
result = task.call();
} catch(Throwable ex) {
future.setException(ex);
throw ex;
}
future.set(result);
}, source);
return future;
}
@Override
default <T> ListenableFuture<T> submit(Callable<T> task) {
return submit(task, Traceables.computeStackTrace(task, CatchingExecutorService.class));
}
default <T> ListenableFuture<T> submit(ThrowingRunnable<?> task, T result, @Nullable StackTrace source) {
final SettableFuture<T> future = SettableFuture.create();
executeCatch(() -> {
try {
task.runThrows();
} catch(Throwable ex) {
future.setException(ex);
throw ex;
}
future.set(result);
}, source);
return future;
}
default <T> ListenableFuture<T> submit(ThrowingRunnable<?> task, T result) {
return submit(task, result, Traceables.computeStackTrace(task, CatchingExecutorService.class));
}
default ListenableFuture<?> submit(ThrowingRunnable<?> task, @Nullable StackTrace source) {
return submit(task, null, source);
}
default ListenableFuture<?> submit(ThrowingRunnable<?> task) {
return submit(task, Traceables.computeStackTrace(task, CatchingExecutorService.class));
}
default <T> ListenableFuture<T> submit(Runnable task, T result, @Nullable StackTrace source) {
return submit((ThrowingRunnable<?>) task::run, result, source);
}
@Override
default <T> ListenableFuture<T> submit(Runnable task, T result) {
return submit(task, result, Traceables.computeStackTrace(task, CatchingExecutorService.class));
}
default ListenableFuture<?> submit(Runnable task, @Nullable StackTrace source) {
return submit((ThrowingRunnable<?>) task::run, source);
}
@Override
default ListenableFuture<?> submit(Runnable task) {
return submit(task, Traceables.computeStackTrace(task, CatchingExecutorService.class));
}
}