
io.github.vipcxj.jasync.ng.runtime.schedule.AllPromisesTask 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 java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AllPromisesTask implements Task> {
private final List> promises;
private final int num;
private final Object[] values;
private volatile int resolvedNum = 0;
@SuppressWarnings("rawtypes")
private static final AtomicIntegerFieldUpdater RESOLVED_NUM_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AllPromisesTask.class, "resolvedNum");
@SuppressWarnings("unused")
private volatile int rejected = 0;
@SuppressWarnings("rawtypes")
private static final AtomicIntegerFieldUpdater REJECTED_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AllPromisesTask.class, "rejected");
public AllPromisesTask(List> promises) {
this.promises = promises;
this.num = promises.size();
this.values = new Object[this.num];
}
@Override
public void schedule(JThunk> thunk, JContext context) {
int i = 0;
for (JPromise extends T> promise : promises) {
int index = i++;
promise.onSuccess((v, ctx) -> {
int resolvedNum = RESOLVED_NUM_UPDATER.incrementAndGet(this);
values[index] = v;
if (resolvedNum == num) {
List result = new ArrayList<>(num);
for (Object value : values) {
//noinspection unchecked
result.add((T) value);
}
thunk.resolve(result, context);
}
}).onError((error, ctx) -> {
if (REJECTED_UPDATER.compareAndSet(this, 0, 1)) {
for (JPromise extends T> promise2 : promises) {
if (promise2 != promise) {
promise2.cancel();
}
}
thunk.reject(error, context);
}
}).async(context.fork());
}
}
@Override
public void cancel() {
for (JPromise extends T> promise : promises) {
promise.cancel();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy