catch RejectedExecutionException

This commit is contained in:
WhatCats
2024-05-25 21:13:20 +02:00
parent daa05d93a0
commit 363669d2c6
2 changed files with 56 additions and 20 deletions

View File

@@ -150,9 +150,13 @@ public abstract class AbstractPromise<T, F> implements Promise<T> {
Promise<V> promise = getFactory().unresolved(); Promise<V> promise = getFactory().unresolved();
addDirectListener( addDirectListener(
res -> { res -> {
Runnable runnable = createRunnable(res, promise, task); try {
F future = getExecutor().runSync(runnable); Runnable runnable = createRunnable(res, promise, task);
promise.onCancel((e) -> getExecutor().cancel(future)); F future = getExecutor().runSync(runnable);
promise.onCancel((e) -> getExecutor().cancel(future));
} catch (RejectedExecutionException e) {
promise.completeExceptionally(e);
}
}, },
promise::completeExceptionally promise::completeExceptionally
); );
@@ -166,9 +170,13 @@ public abstract class AbstractPromise<T, F> implements Promise<T> {
Promise<V> promise = getFactory().unresolved(); Promise<V> promise = getFactory().unresolved();
addDirectListener( addDirectListener(
res -> { res -> {
Runnable runnable = createRunnable(res, promise, task); try {
F future = getExecutor().runSync(runnable, delay, unit); Runnable runnable = createRunnable(res, promise, task);
promise.onCancel((e) -> getExecutor().cancel(future)); F future = getExecutor().runSync(runnable, delay, unit);
promise.onCancel((e) -> getExecutor().cancel(future));
} catch (RejectedExecutionException e) {
promise.completeExceptionally(e);
}
}, },
promise::completeExceptionally promise::completeExceptionally
); );
@@ -251,9 +259,13 @@ public abstract class AbstractPromise<T, F> implements Promise<T> {
Promise<V> promise = getFactory().unresolved(); Promise<V> promise = getFactory().unresolved();
addDirectListener( addDirectListener(
(res) -> { (res) -> {
Runnable runnable = createRunnable(res, promise, task); try {
F future = getExecutor().runAsync(runnable); Runnable runnable = createRunnable(res, promise, task);
promise.onCancel((e) -> getExecutor().cancel(future)); F future = getExecutor().runAsync(runnable);
promise.onCancel((e) -> getExecutor().cancel(future));
} catch (RejectedExecutionException e) {
promise.completeExceptionally(e);
}
}, },
promise::completeExceptionally promise::completeExceptionally
); );
@@ -267,9 +279,13 @@ public abstract class AbstractPromise<T, F> implements Promise<T> {
Promise<V> promise = getFactory().unresolved(); Promise<V> promise = getFactory().unresolved();
addDirectListener( addDirectListener(
res -> { res -> {
Runnable runnable = createRunnable(res, promise, task); try {
F future = getExecutor().runAsync(runnable, delay, unit); Runnable runnable = createRunnable(res, promise, task);
promise.onCancel((e) -> getExecutor().cancel(future)); F future = getExecutor().runAsync(runnable, delay, unit);
promise.onCancel((e) -> getExecutor().cancel(future));
} catch (RejectedExecutionException e) {
promise.completeExceptionally(e);
}
}, },
promise::completeExceptionally promise::completeExceptionally
); );
@@ -355,7 +371,11 @@ public abstract class AbstractPromise<T, F> implements Promise<T> {
private void callListener(PromiseListener<T> listener, PromiseCompletion<T> ctx) { private void callListener(PromiseListener<T> listener, PromiseCompletion<T> ctx) {
if (listener instanceof AsyncPromiseListener) { if (listener instanceof AsyncPromiseListener) {
getExecutor().runAsync(() -> callListenerNow(listener, ctx)); try {
getExecutor().runAsync(() -> callListenerNow(listener, ctx));
} catch (RejectedExecutionException ignored) {
}
} else { } else {
callListenerNow(listener, ctx); callListenerNow(listener, ctx);
} }
@@ -407,8 +427,14 @@ public abstract class AbstractPromise<T, F> implements Promise<T> {
@Override @Override
public @NotNull Promise<T> maxWaitTime(long time, @NotNull TimeUnit unit) { public @NotNull Promise<T> maxWaitTime(long time, @NotNull TimeUnit unit) {
F future = getExecutor().runAsync(() -> completeExceptionally(new TimeoutException("Promise stopped waiting after " + time + " " + unit)), time, unit); try {
return addListener((_v) -> getExecutor().cancel(future)); Exception e = new TimeoutException("Promise stopped waiting after " + time + " " + unit);
F future = getExecutor().runAsync(() -> completeExceptionally(e), time, unit);
return addDirectListener((_v) -> getExecutor().cancel(future));
} catch (RejectedExecutionException e) {
completeExceptionally(e);
return this;
}
} }
private void handleCompletion(@NotNull PromiseCompletion<T> ctx) { private void handleCompletion(@NotNull PromiseCompletion<T> ctx) {

View File

@@ -3,6 +3,7 @@ package dev.tommyjs.futur;
import dev.tommyjs.futur.executor.PromiseExecutor; import dev.tommyjs.futur.executor.PromiseExecutor;
import dev.tommyjs.futur.executor.SinglePoolExecutor; import dev.tommyjs.futur.executor.SinglePoolExecutor;
import dev.tommyjs.futur.impl.SimplePromiseFactory; import dev.tommyjs.futur.impl.SimplePromiseFactory;
import dev.tommyjs.futur.promise.Promise;
import dev.tommyjs.futur.promise.PromiseFactory; import dev.tommyjs.futur.promise.PromiseFactory;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -12,16 +13,14 @@ import reactor.core.publisher.Mono;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Future; import java.util.concurrent.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public final class PromiseTests { public final class PromiseTests {
private final Logger logger = LoggerFactory.getLogger(PromiseTests.class); private final Logger logger = LoggerFactory.getLogger(PromiseTests.class);
private final PromiseExecutor<Future<?>> executor = SinglePoolExecutor.create(5); private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
private final PromiseFactory pfac = new SimplePromiseFactory<>(executor, logger); private final PromiseFactory pfac = new SimplePromiseFactory<>(new SinglePoolExecutor(executor), logger);
@Test @Test
public void testMono() { public void testMono() {
@@ -36,6 +35,17 @@ public final class PromiseTests {
assert resolved.getCompletion().getResult() == value; assert resolved.getCompletion().getResult() == value;
} }
@Test
public void testShutdown() {
executor.close();
Promise<?> promise = pfac.resolve(null).thenSupplyAsync(() -> null);
try {
promise.await();
} catch (RuntimeException e) {
assert e.getCause() instanceof RejectedExecutionException;
}
}
@Test @Test
public void testErrorCancellation() throws InterruptedException { public void testErrorCancellation() throws InterruptedException {
var finished = new AtomicBoolean(); var finished = new AtomicBoolean();