mirror of
https://github.com/tommyskeff/futur4j.git
synced 2026-01-18 07:16:45 +00:00
documentation and small changes
- added docs for `Promise` and `PromiseFactory` - removed outdated README docs - moved some common utilities to `PromiseUtil` - improved efficiency of result array resizing - added cancellation result to promise executors - changed visibility of `PromiseJoiner` to public, and made some method names more verbose - inlined `DeferredExecutionException` to inside `AbstractPromise` - inlined default promise implementation to inner class in the factory - removed necessity for base factories to provide a logger
This commit is contained in:
@@ -3,6 +3,7 @@ package dev.tommyjs.futur.joiner;
|
||||
import dev.tommyjs.futur.promise.Promise;
|
||||
import dev.tommyjs.futur.promise.PromiseCompletion;
|
||||
import dev.tommyjs.futur.promise.PromiseFactory;
|
||||
import dev.tommyjs.futur.util.ConcurrentResultArray;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -24,18 +25,18 @@ public class CompletionJoiner extends PromiseJoiner<Promise<?>, Void, Void, List
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void getKey(Promise<?> value) {
|
||||
protected Void getChildKey(Promise<?> value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Promise<Void> getPromise(Promise<?> value) {
|
||||
protected @NotNull Promise<Void> getChildPromise(Promise<?> value) {
|
||||
//noinspection unchecked
|
||||
return (Promise<Void>) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Throwable onFinish(int index, Void key, @NotNull PromiseCompletion<Void> res) {
|
||||
protected @Nullable Throwable onChildComplete(int index, Void key, @NotNull PromiseCompletion<Void> res) {
|
||||
results.set(index, res);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package dev.tommyjs.futur.joiner;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
class ConcurrentResultArray<T> {
|
||||
|
||||
private final AtomicReference<T[]> ref;
|
||||
|
||||
public ConcurrentResultArray(int expectedSize) {
|
||||
//noinspection unchecked
|
||||
this.ref = new AtomicReference<>((T[]) new Object[expectedSize]);
|
||||
}
|
||||
|
||||
public void set(int index, T element) {
|
||||
ref.updateAndGet(array -> {
|
||||
if (array.length <= index)
|
||||
return Arrays.copyOf(array, index + 6);
|
||||
|
||||
array[index] = element;
|
||||
return array;
|
||||
});
|
||||
}
|
||||
|
||||
public @NotNull List<T> toList() {
|
||||
return Arrays.asList(ref.get());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package dev.tommyjs.futur.joiner;
|
||||
import dev.tommyjs.futur.promise.Promise;
|
||||
import dev.tommyjs.futur.promise.PromiseCompletion;
|
||||
import dev.tommyjs.futur.promise.PromiseFactory;
|
||||
import dev.tommyjs.futur.util.ConcurrentResultArray;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -27,19 +28,22 @@ public class MappedResultJoiner<K, V> extends PromiseJoiner<Map.Entry<K, Promise
|
||||
}
|
||||
|
||||
@Override
|
||||
protected K getKey(Map.Entry<K, Promise<V>> entry) {
|
||||
protected K getChildKey(Map.Entry<K, Promise<V>> entry) {
|
||||
return entry.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Promise<V> getPromise(Map.Entry<K, Promise<V>> entry) {
|
||||
protected @NotNull Promise<V> getChildPromise(Map.Entry<K, Promise<V>> entry) {
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Throwable onFinish(int index, K key, @NotNull PromiseCompletion<V> res) {
|
||||
protected @Nullable Throwable onChildComplete(int index, K key, @NotNull PromiseCompletion<V> res) {
|
||||
if (res.isError()) {
|
||||
if (exceptionHandler == null) return res.getException();
|
||||
if (exceptionHandler == null) {
|
||||
return res.getException();
|
||||
}
|
||||
|
||||
exceptionHandler.accept(key, res.getException());
|
||||
}
|
||||
|
||||
@@ -54,6 +58,7 @@ public class MappedResultJoiner<K, V> extends PromiseJoiner<Map.Entry<K, Promise
|
||||
for (Map.Entry<K, V> entry : list) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package dev.tommyjs.futur.joiner;
|
||||
|
||||
import dev.tommyjs.futur.promise.*;
|
||||
import dev.tommyjs.futur.promise.CompletablePromise;
|
||||
import dev.tommyjs.futur.promise.Promise;
|
||||
import dev.tommyjs.futur.promise.PromiseCompletion;
|
||||
import dev.tommyjs.futur.promise.PromiseFactory;
|
||||
import dev.tommyjs.futur.util.PromiseUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -8,7 +12,7 @@ import java.util.Iterator;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
abstract class PromiseJoiner<V, K, T, R> {
|
||||
public abstract class PromiseJoiner<V, K, T, R> {
|
||||
|
||||
private final CompletablePromise<R> joined;
|
||||
|
||||
@@ -16,15 +20,11 @@ abstract class PromiseJoiner<V, K, T, R> {
|
||||
this.joined = factory.unresolved();
|
||||
}
|
||||
|
||||
public @NotNull Promise<R> joined() {
|
||||
return joined;
|
||||
}
|
||||
protected abstract K getChildKey(V value);
|
||||
|
||||
protected abstract K getKey(V value);
|
||||
protected abstract @NotNull Promise<T> getChildPromise(V value);
|
||||
|
||||
protected abstract @NotNull Promise<T> getPromise(V value);
|
||||
|
||||
protected abstract @Nullable Throwable onFinish(int index, K key, @NotNull PromiseCompletion<T> completion);
|
||||
protected abstract @Nullable Throwable onChildComplete(int index, K key, @NotNull PromiseCompletion<T> completion);
|
||||
|
||||
protected abstract R getResult();
|
||||
|
||||
@@ -35,18 +35,19 @@ abstract class PromiseJoiner<V, K, T, R> {
|
||||
int i = 0;
|
||||
do {
|
||||
V value = promises.next();
|
||||
Promise<T> p = getPromise(value);
|
||||
Promise<T> p = getChildPromise(value);
|
||||
|
||||
if (link) {
|
||||
AbstractPromise.cancelOnFinish(p, joined);
|
||||
PromiseUtil.cancelOnComplete(joined, p);
|
||||
}
|
||||
|
||||
if (!joined.isCompleted()) {
|
||||
count.incrementAndGet();
|
||||
K key = getKey(value);
|
||||
K key = getChildKey(value);
|
||||
int index = i++;
|
||||
|
||||
p.addListener((res) -> {
|
||||
Throwable e = onFinish(index, key, res);
|
||||
p.addAsyncListener(res -> {
|
||||
Throwable e = onChildComplete(index, key, res);
|
||||
if (e != null) {
|
||||
joined.completeExceptionally(e);
|
||||
} else if (count.decrementAndGet() == 0 && waiting.get()) {
|
||||
@@ -56,11 +57,17 @@ abstract class PromiseJoiner<V, K, T, R> {
|
||||
}
|
||||
} while (promises.hasNext());
|
||||
|
||||
count.updateAndGet((v) -> {
|
||||
if (v == 0) joined.complete(getResult());
|
||||
else waiting.set(true);
|
||||
return v;
|
||||
});
|
||||
if (!joined.isCompleted()) {
|
||||
count.updateAndGet(v -> {
|
||||
if (v == 0) joined.complete(getResult());
|
||||
else waiting.set(true);
|
||||
return v;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull Promise<R> joined() {
|
||||
return joined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.tommyjs.futur.joiner;
|
||||
import dev.tommyjs.futur.promise.Promise;
|
||||
import dev.tommyjs.futur.promise.PromiseCompletion;
|
||||
import dev.tommyjs.futur.promise.PromiseFactory;
|
||||
import dev.tommyjs.futur.util.ConcurrentResultArray;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -28,19 +29,22 @@ public class ResultJoiner<T> extends PromiseJoiner<Promise<T>, Void, T, List<T>>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void getKey(Promise<T> value) {
|
||||
protected Void getChildKey(Promise<T> value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Promise<T> getPromise(Promise<T> value) {
|
||||
protected @NotNull Promise<T> getChildPromise(Promise<T> value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Throwable onFinish(int index, Void key, @NotNull PromiseCompletion<T> res) {
|
||||
protected @Nullable Throwable onChildComplete(int index, Void key, @NotNull PromiseCompletion<T> res) {
|
||||
if (res.isError()) {
|
||||
if (exceptionHandler == null) return res.getException();
|
||||
if (exceptionHandler == null) {
|
||||
return res.getException();
|
||||
}
|
||||
|
||||
exceptionHandler.accept(index, res.getException());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,18 +16,18 @@ public class VoidJoiner extends PromiseJoiner<Promise<?>, Void, Void, Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void getKey(Promise<?> value) {
|
||||
protected Void getChildKey(Promise<?> value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Promise<Void> getPromise(Promise<?> value) {
|
||||
protected @NotNull Promise<Void> getChildPromise(Promise<?> value) {
|
||||
//noinspection unchecked
|
||||
return (Promise<Void>) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Throwable onFinish(int index, Void key, @NotNull PromiseCompletion<Void> completion) {
|
||||
protected @Nullable Throwable onChildComplete(int index, Void key, @NotNull PromiseCompletion<Void> completion) {
|
||||
return completion.getException();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user