
io.github.vipcxj.jasync.ng.runtime.schedule.AnyPromiseTask Maven / Gradle / Ivy
package io.github.vipcxj.jasync.ng.runtime.schedule;
import io.github.vipcxj.jasync.ng.spec.JContext;
import io.github.vipcxj.jasync.ng.spec.JPromise;
import io.github.vipcxj.jasync.ng.spec.JThunk;
import io.github.vipcxj.jasync.ng.spec.exceptions.JAsyncCompositeException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AnyPromiseTask implements Task {
private final List> promises;
private final List errors;
@SuppressWarnings("unused")
private volatile int resolved = 0;
@SuppressWarnings("rawtypes")
private static final AtomicIntegerFieldUpdater RESOLVED_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AnyPromiseTask.class, "resolved");
private volatile int errorNum = 0;
@SuppressWarnings("rawtypes")
private static final AtomicIntegerFieldUpdater ERROR_NUM_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AnyPromiseTask.class, "errorNum");
public AnyPromiseTask(List> promises) {
this.promises = promises;
this.errors = new ArrayList<>(promises.size());
for (int i = 0; i < promises.size(); ++i) {
this.errors.add(i, null);
}
}
@Override
public void schedule(JThunk thunk, JContext context) {
int i = 0;
for (JPromise extends T> promise : promises) {
int finalI = i;
promise.onSuccess((v, ctx) -> {
if (RESOLVED_UPDATER.compareAndSet(this, 0, 1)) {
for (JPromise extends T> promise2 : promises) {
if (promise2 != promise) {
promise2.cancel();
}
}
thunk.resolve(v, context);
}
}).onError((error, ctx) -> {
int errorNum = ERROR_NUM_UPDATER.incrementAndGet(this);
errors.set(finalI, error);
if (errorNum == promises.size()) {
thunk.reject(new JAsyncCompositeException(errors), context);
}
}).async(context.fork());
++i;
}
}
@Override
public void cancel() {
for (JPromise extends T> promise : promises) {
promise.cancel();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy