All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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 promise2 : promises) {
                        if (promise2 != promise) {
                            promise2.cancel();
                        }
                    }
                    thunk.reject(error, context);
                }
            }).async(context.fork());
        }

    }

    @Override
    public void cancel() {
        for (JPromise promise : promises) {
            promise.cancel();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy