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

io.github.vipcxj.jasync.ng.spec.JPromise Maven / Gradle / Ivy

Go to download

JAsync implements Async-Await fashion for Java just like es and c#. This library provide the spec of all public api.

There is a newer version: 1.0.17
Show newest version
package io.github.vipcxj.jasync.ng.spec;

import io.github.vipcxj.jasync.ng.spec.functional.*;
import io.github.vipcxj.jasync.ng.spec.spi.JPromiseSupport;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

@SuppressWarnings("unused")
public interface JPromise extends JHandle {
    JPromiseSupport provider = Utils.getProvider(JPromiseSupport.class);
    static int genId() {
        return provider.generateId();
    }
    static  JPromise just(T value) {
        return provider.just(value);
    }
    static  JPromise empty() {
        return provider.just(null);
    }
    static  JPromise error(Throwable error) {
        return provider.error(error);
    }
    static JPromise sleep(long timeout, TimeUnit unit) {
        return provider.sleep(timeout, unit);
    }
    static  JPromise portal(JAsyncPortalTask1 task) {
        return provider.portal(task);
    }
    static  JPromise portal(JAsyncPortalTask0 task) {
        return portal((factory, context) -> task.invoke(factory));
    }
    static  JPromise portal(JAsyncPromiseFunction0 task, int jumpIndex, Object... locals) {
        JPromise promise = updateContext(ctx -> ctx.pushLocals(locals))
                .thenImmediate(() ->
                        portal((factory, context) -> {
                                    Object[] theLocals = context.getLocals();
                                    return updateContext(ctx -> ctx.popLocals().setPortal(jumpIndex, factory))
                                            .thenImmediate(() -> task.apply(theLocals));
                                }
                        ));
        return promise.withUpdateContext(ctx -> ctx.removePortal(jumpIndex));
    }
    static  JPromise portal(JAsyncPromiseFunction1 task, int jumpIndex, Object... locals) {
        JPromise promise = updateContext(ctx -> ctx.pushLocals(locals))
                .thenImmediate(() ->
                        portal((factory, context) -> {
                                    Object[] theLocals = context.getLocals();
                                    return updateContext(ctx -> ctx.popLocals().setPortal(jumpIndex, factory))
                                            .thenWithContextImmediate(ctx -> task.apply(theLocals, ctx));
                                }
                        ));
        return promise.withUpdateContext(ctx -> ctx.removePortal(jumpIndex));
    }
    static  JPromise jump(int jumpIndex, Object... localVars) {
        return updateContext(ctx -> ctx.pushLocals(localVars)).thenImmediate(ctx -> ctx.jump(jumpIndex));
    }
    static JAsyncReadWriteLock readWriteLock() {
        return provider.readWriteLock();
    }
    static  JPromise methodDebugInfo(JAsyncPromiseSupplier1 supplier, String declaringClassQualifiedName, String method, String fileName) {
        return updateContext(ctx -> ctx.pushStackFrame(declaringClassQualifiedName, method, fileName)).thenWithContextImmediate(supplier).withUpdateContext(JContext::popStackFrame);
    }
    static  JPromise wrap(JAsyncPromiseSupplier0 supplier) {
        return JPromise.empty().thenImmediate(supplier);
    }
    static  JPromise wrap(JAsyncPromiseSupplier1 supplier) {
        return JPromise.empty().thenWithContextImmediate(supplier);
    }
    @SafeVarargs
    static   JPromise any(JPromise... promises) {
        return provider.any(promises);
    }
    static   JPromise any(List> promises) {
        return provider.any(promises);
    }
    @SafeVarargs
    static   JPromise race(JPromise... promises) {
        return provider.race(promises);
    }
    static   JPromise race(List> promises) {
        return provider.race(promises);
    }
    static  JPromise> all(List> promises) {
        return provider.all(promises);
    }
    @SafeVarargs
    static   JPromise> all(JPromise... promises) {
        return provider.all(promises);
    }

    /**
     * Create a lazy promise. The handler will be scheduled by the scheduler.
     * @param handler the promise handler.
     * @param  the promise type.
     * @return the promise.
     */
    static  JPromise create(BiConsumer, JContext> handler) {
        return provider.create(handler);
    }
    /**
     * Create a immediate promise. The handler will be invoked in the current thread just after async or block called.
     * @param handler the promise handler.
     * @param  the promise type.
     * @return the promise.
     */
    static  JPromise generate(BiConsumer, JContext> handler) {
        return provider.generate(handler);
    }

    static  JPromiseTrigger createTrigger() {
        return provider.createTrigger();
    }

    static JPromise context() {
        return JPromise.generate(Functions.PROMISE_HANDLER_EXTRACT_CONTEXT);
    }

    static JPromise updateContext(JContext context) {
        return JPromise.generate((thunk, oldContext) -> {
            thunk.resolve(oldContext, context);
        });
    }

    static JPromise updateContext(Function contextUpdater) {
        return JPromise.generate((thunk, context) -> {
            JContext newContext = contextUpdater.apply(context);
            thunk.resolve(context, newContext);
        });
    }

    static  JPromise wrapContext(JPromise promise, JContext context) {
        return updateContext(context).thenImmediate(promise::withUpdateContext);
    }

    static  JPromise wrapContext(JPromise promise, Function contextUpdater) {
        return updateContext(contextUpdater).thenImmediate(promise::withUpdateContext);
    }

    static  JPromise wrapContext(JAsyncPromiseFunction0 function, JContext context) {
        return updateContext(context).thenWithContextImmediate((oldContext, newContext) -> function.apply(newContext).withUpdateContext(oldContext));
    }

    static  JPromise wrapContext(JAsyncPromiseFunction0 function, Function contextUpdater) {
        return updateContext(contextUpdater).thenWithContextImmediate((oldContext, newContext) -> function.apply(newContext).withUpdateContext(oldContext));
    }

    static  JPromise wrapContext(JAsyncPromiseSupplier0 function, JContext context) {
        return updateContext(context).thenImmediate((oldContext) -> function.get().withUpdateContext(oldContext));
    }

    static  JPromise wrapContext(JAsyncPromiseSupplier0 function, Function contextUpdater) {
        return updateContext(contextUpdater).thenImmediate((oldContext) -> function.get().withUpdateContext(oldContext));
    }

    static JPromise updateScheduler(JScheduler scheduler) {
        return JPromise.generate((thunk, context) -> {
            JScheduler oldScheduler = context.getScheduler();
            JContext newContext = context.setScheduler(scheduler);
            thunk.resolve(oldScheduler, newContext);
        });
    }

    static  JPromise wrapScheduler(JPromise promise, JScheduler scheduler) {
        return updateScheduler(scheduler).thenImmediate(promise::withUpdateScheduler);
    }

    static  JPromise wrapScheduler(JAsyncPromiseSupplier0 function, JScheduler scheduler) {
        return updateScheduler(scheduler).thenImmediate((oldScheduler) -> function.get().withUpdateScheduler(oldScheduler));
    }

    static JPromise hasContextValue(Object key) {
        return JPromise.generate((thunk, context) -> {
            thunk.resolve(context.hasKey(key), context);
        });
    }

    static  JPromise getContextValue(Object key) {
        return JPromise.generate((thunk, context) -> {
            thunk.resolve(context.get(key), context);
        });
    }

    static  JPromise getContextValue(Object key, T defaultValue) {
        return JPromise.generate((thunk, context) -> {
            thunk.resolve(context.getOrDefault(key, defaultValue), context);
        });
    }

    static  JPromise> getContextValueOrEmpty(Object key) {
        return JPromise.generate((thunk, context) -> {
            thunk.resolve(context.getOrEmpty(key), context);
        });
    }

    static JPromise getScheduler() {
        return JPromise.generate(Functions.PROMISE_HANDLER_EXTRACT_SCHEDULER);
    }

    static  JPromise setContextValue(Object key, Object newValue) {
        return JPromise.generate((thunk, context) -> {
            Object old = context.get(key);
            JContext newContext = context.set(key, newValue);
            //noinspection unchecked
            thunk.resolve((T) old, newContext);
        });
    }

    static JPromise updateContextValue(Object key, Function valueUpdater) {
        return JPromise.generate((thunk, context) -> {
            Object value = context.get(key);
            JContext newContext = context.set(key, valueUpdater.apply(value));
            thunk.resolve(null, newContext);
        });
    }

    static  JPromise updateContextValue(Object key, Function valueUpdater, E emptyValue) {
        return JPromise.generate((thunk, context) -> {
            if (context.hasKey(key)) {
                E value = context.get(key);
                JContext newContext = context.set(key, valueUpdater.apply(value));
                thunk.resolve(null, newContext);
            } else {
                JContext newContext = context.set(key, emptyValue);
                thunk.resolve(null, newContext);
            }
        });
    }

    static JPromise setContextValueIfExists(Object key, Object newValue) {
        return JPromise.generate((thunk, context) -> {
            if (context.hasKey(key)) {
                JContext newContext = context.set(key, newValue);
                thunk.resolve(true, newContext);
            } else {
                thunk.resolve(false, context);
            }
        });
    }

    static JPromise updateContextValueIfExists(Object key, Function valueUpdater) {
        return JPromise.generate((thunk, context) -> {
            if (context.hasKey(key)) {
                Object value = context.get(key);
                JContext newContext = context.set(key, valueUpdater.apply(value));
                thunk.resolve(null, newContext);
            } else {
                thunk.resolve(null, context);
            }
        });
    }

    static  JPromise removeContextValue(Object key) {
        return JPromise.generate((thunk, context) -> {
            Object old = context.get(key);
            JContext newContext = context.remove(key);
            //noinspection unchecked
            thunk.resolve((T) old, newContext);
        });
    }

    default T await() throws InterruptedException {
        throw new UnsupportedOperationException("The method \"await\" should be called in an async method.");
    }
     JPromise thenWithContext(JAsyncPromiseFunction1 mapper, boolean immediate);
    default  JPromise thenWithContext(JAsyncPromiseFunction1 mapper) {
        return thenWithContext(mapper, false);
    }
    default  JPromise thenWithContextImmediate(JAsyncPromiseFunction1 mapper) {
        return thenWithContext(mapper, true);
    }

    default  JPromise then(JAsyncPromiseFunction0 mapper, boolean immediate) {
        return thenWithContext((v, ctx) -> mapper.apply(v), immediate);
    }
    default  JPromise then(JAsyncPromiseFunction0 mapper) {
        return then(mapper, false);
    }
    default  JPromise thenImmediate(JAsyncPromiseFunction0 mapper) {
        return then(mapper, true);
    }

    default  JPromise thenWithContext(JAsyncPromiseSupplier1 supplier, boolean immediate) {
        return thenWithContext((ignored, ctx) -> supplier.get(ctx), immediate);
    }
    default  JPromise thenWithContext(JAsyncPromiseSupplier1 supplier) {
        return thenWithContext(supplier, false);
    }
    default  JPromise thenWithContextImmediate(JAsyncPromiseSupplier1 supplier) {
        return thenWithContext(supplier, true);
    }

    default  JPromise then(JAsyncPromiseSupplier0 supplier, boolean immediate) {
        return then((T ignored) -> supplier.get(), immediate);
    }
    default  JPromise then(JAsyncPromiseSupplier0 supplier) {
        return then(supplier, false);
    }
    default  JPromise thenImmediate(JAsyncPromiseSupplier0 supplier) {
        return then(supplier, true);
    }

    default  JPromise thenMapWithContext(JAsyncFunction1 function, boolean immediate) {
        return thenWithContext((T v, JContext ctx) -> JPromise.just(function.apply(v, ctx)), immediate);
    }
    default  JPromise thenMapWithContext(JAsyncFunction1 function) {
        return thenMapWithContext(function, false);
    }
    default  JPromise thenMapWithContextImmediate(JAsyncFunction1 function) {
        return thenMapWithContext(function, true);
    }

    default  JPromise thenMap(JAsyncFunction0 function, boolean immediate) {
        return then((T v) -> JPromise.just(function.apply(v)), immediate);
    }
    default  JPromise thenMap(JAsyncFunction0 function) {
        return thenMap(function, false);
    }
    default  JPromise thenMapImmediate(JAsyncFunction0 function) {
        return thenMap(function, true);
    }

    default  JPromise thenMapWithContext(JAsyncSupplier1 function, boolean immediate) {
        return thenWithContext((v, ctx) -> JPromise.just(function.get(ctx)), immediate);
    }
    default  JPromise thenMapWithContext(JAsyncSupplier1 function) {
        return thenMapWithContext(function, false);
    }
    default  JPromise thenMapWithContextImmediate(JAsyncSupplier1 function) {
        return thenMapWithContext(function, true);
    }

    default  JPromise thenMap(JAsyncSupplier0 function, boolean immediate) {
        return then((T v) -> JPromise.just(function.get()), immediate);
    }
    default  JPromise thenMap(JAsyncSupplier0 function) {
        return thenMap(function, false);
    }
    default  JPromise thenMapImmediate(JAsyncSupplier0 function) {
        return thenMap(function, true);
    }

    default  JPromise thenWithWithContext(JAsyncPromiseFunction1 function, boolean immediate) {
        return thenWithContext((v, ctx) -> function.apply(v, ctx).thenReturn(v), immediate);
    }
    default  JPromise thenWithWithContext(JAsyncPromiseFunction1 function) {
        return thenWithWithContext(function, false);
    }
    default  JPromise thenWithWithContextImmediate(JAsyncPromiseFunction1 function) {
        return thenWithWithContext(function, true);
    }

    default  JPromise thenWith(JAsyncPromiseFunction0 function, boolean immediate) {
        return then(v -> function.apply(v).thenReturn(v), immediate);
    }
    default  JPromise thenWith(JAsyncPromiseFunction0 function) {
        return thenWith(function, false);
    }
    default  JPromise thenWithImmediate(JAsyncPromiseFunction0 function) {
        return thenWith(function, true);
    }

    default  JPromise thenWithWithContext(JAsyncPromiseSupplier1 supplier, boolean immediate) {
        return thenWithContext((v, ctx) -> supplier.get(ctx).thenReturn(v), immediate);
    }
    default  JPromise thenWithWithContext(JAsyncPromiseSupplier1 supplier) {
        return thenWithWithContext(supplier, false);
    }
    default  JPromise thenWithWithContextImmediate(JAsyncPromiseSupplier1 supplier) {
        return thenWithWithContext(supplier, true);
    }

    default  JPromise thenWith(JAsyncPromiseSupplier0 supplier, boolean immediate) {
        return then(v -> supplier.get().thenReturn(v), immediate);
    }
    default  JPromise thenWith(JAsyncPromiseSupplier0 supplier) {
        return thenWith(supplier, false);
    }
    default  JPromise thenWithImmediate(JAsyncPromiseSupplier0 supplier) {
        return thenWith(supplier, true);
    }

    default  JPromise thenReturn(R next) {
        return thenMapImmediate(() -> next);
    }

    default  JPromise thenVoid() {
        return thenReturn(null);
    }

    default  JPromise thenPromise(JPromise nextPromise) {
        return thenImmediate(() -> nextPromise);
    }

    default JPromise withContext(Consumer consumer) {
        return thenWithWithContextImmediate((JContext context) -> {
            consumer.accept(context);
            return JPromise.empty();
        });
    }
    default JPromise withUpdateContext(JContext context) {
        return thenWithImmediate(() -> updateContext(ctx -> context));
    }
    default JPromise withUpdateContext(Function contextUpdater) {
        return thenWithImmediate(() -> updateContext(contextUpdater));
    }
    default JPromise withSetContextValue(Object key, Object value) {
        return thenWithImmediate(() -> setContextValue(key, value));
    }
    default JPromise withRemoveContextValue(Object key) {
        return thenWithImmediate(() -> removeContextValue(key));
    }
    default JPromise withUpdateContextValue(Object key, Function updater, Object emptyValue) {
        return thenWithImmediate(() -> updateContextValue(key, updater, emptyValue));
    }
    default JPromise withUpdateContextValueIfExists(Object key, Function updater) {
        return thenWithImmediate(() -> updateContextValueIfExists(key, updater));
    }
    default JPromise withUpdateScheduler(JScheduler scheduler) {
        return thenWithImmediate(() -> updateScheduler(scheduler));
    }

    default JPromise delay(long timeout, TimeUnit unit) {
        return thenWith(() -> sleep(timeout, unit));
    }

    JPromise doCatchWithContext(JAsyncCatchFunction1 catcher, boolean immediate);
    default JPromise doCatchWithContext(JAsyncCatchFunction1 catcher) {
        return doCatchWithContext(catcher, false);
    }
    default JPromise doCatchWithContextImmediate(JAsyncCatchFunction1 catcher) {
        return doCatchWithContext(catcher, true);
    }

    default JPromise doCatch(JAsyncCatchFunction0 catcher, boolean immediate) {
        return doCatchWithContext((error, ctx) -> catcher.apply(error), immediate);
    }
    default JPromise doCatch(JAsyncCatchFunction0 catcher) {
        return doCatch(catcher, false);
    }
    default JPromise doCatchImmediate(JAsyncCatchFunction0 catcher) {
        return doCatch(catcher, true);
    }

    String MULTI_CATCH_ARGS_ERROR = "The arguments exceptionTypeAndCatches composed with throwable class and JPromiseCatchFunction0 or JPromiseCatchFunction1 pairs.";

    /**
     * 
     * JAsyncCatchFunction1 closure1 = (e, ctx) -> { ... }
     * JAsyncCatchFunction0 closure2 = (e) -> { ... }
     * promise.doMultiCatches(
     *   immediate,
     *   IllegalArgumentException.class, closure1,
     *   RuntimeException.class, closure2
     * )
     * 
* equals to: *
     * promise.doCatch(immediate, (e, ctx) -> {
     *     if (e instanceof IllegalArgumentException) {
     *         return closure1.apply(e, ctx);
     *     } else if (e instanceof RuntimeException) {
     *         return closure2.apply(e);
     *     } else {
     *         throw e;
     *     }
     * })
     * 
* * @param immediate whether invoke the closure immediate ignore the current scheduler * @param exceptionTypeAndCatches exception type and catch closure pairs. * Both JAsyncCatchFunction0 and JAsyncCatchFunction1 are supported. * @return the promise */ default JPromise doMultiCatches(boolean immediate, Object... exceptionTypeAndCatches) { if ((exceptionTypeAndCatches.length & 1) == 1) { throw new IllegalArgumentException("The number of arguments exceptionTypeAndCatches must be even."); } for (int i = 0; i < exceptionTypeAndCatches.length;) { Object arg = exceptionTypeAndCatches[i++]; if (!(arg instanceof Class)) { throw new IllegalArgumentException(MULTI_CATCH_ARGS_ERROR); } Class exceptionType = (Class) arg; if (!Throwable.class.isAssignableFrom(exceptionType)) { throw new IllegalArgumentException(MULTI_CATCH_ARGS_ERROR); } arg = exceptionTypeAndCatches[i++]; if (!(arg instanceof JAsyncCatchFunction0) && !(arg instanceof JAsyncCatchFunction1)) { throw new IllegalArgumentException(MULTI_CATCH_ARGS_ERROR); } } return doCatchWithContext((e, ctx) -> { for (int i = 0; i < exceptionTypeAndCatches.length;) { Class exceptionType = (Class) exceptionTypeAndCatches[i++]; Object closure = exceptionTypeAndCatches[i++]; if (exceptionType.isInstance(e)) { if (closure instanceof JAsyncCatchFunction0) { //noinspection unchecked return ((JAsyncCatchFunction0) closure).apply(e); } else { //noinspection unchecked return ((JAsyncCatchFunction1) closure).apply(e, ctx); } } } throw e; }, immediate); } /** * same as doMultiCatches(false, exceptionTypeAndCatches) * @param exceptionTypeAndCatches exception type and catch closure pairs. * Both JAsyncCatchFunction0 and JAsyncCatchFunction1 are supported. * @return the promise * @see #doMultiCatches(boolean, Object...) */ default JPromise doMultiCatches(Object... exceptionTypeAndCatches) { return doMultiCatches(false, exceptionTypeAndCatches); } /** * same as doMultiCatches(true, exceptionTypeAndCatches) * @param exceptionTypeAndCatches exception type and catch closure pairs. * Both JAsyncCatchFunction0 and JAsyncCatchFunction1 are supported. * @return the promise * @see #doMultiCatches(boolean, Object...) */ default JPromise doMultiCatchImmediate(Object... exceptionTypeAndCatches) { return doMultiCatches(true, exceptionTypeAndCatches); } JPromise thenOrCatchWithContext(JAsyncPromiseFunction3 handler, boolean immediate); default JPromise thenOrCatchWithContext(JAsyncPromiseFunction3 handler) { return thenOrCatchWithContext(handler, false); } default JPromise thenOrCatchWithContextImmediate(JAsyncPromiseFunction3 handler) { return thenOrCatchWithContext(handler, true); } default JPromise thenOrCatch(JAsyncPromiseFunction2 handler) { return thenOrCatchWithContext((t, throwable, context) -> handler.apply(t, throwable)); } default JPromise thenOrCatchImmediate(JAsyncPromiseFunction2 handler) { return thenOrCatchWithContext((t, throwable, context) -> handler.apply(t, throwable), true); } JPromise doFinallyWithContext(JAsyncPromiseSupplier1 supplier, boolean immediate); default JPromise doFinallyWithContext(JAsyncPromiseSupplier1 supplier) { return doFinallyWithContext(supplier, false); } default JPromise doFinallyWithContextImmediate(JAsyncPromiseSupplier1 supplier) { return doFinallyWithContext(supplier, true); } default JPromise doFinally(JAsyncPromiseSupplier0 supplier, boolean immediate) { return doFinallyWithContext(ctx -> supplier.get(), immediate); } default JPromise doFinally(JAsyncPromiseSupplier0 supplier) { return doFinally(supplier, false); } default JPromise doFinallyImmediate(JAsyncPromiseSupplier0 supplier) { return doFinally(supplier, true); } JPromise onSuccess(BiConsumer resolver); default JPromise onSuccess(Consumer consumer) { return onSuccess((v, ctx) -> consumer.accept(v)); } JPromise onError(BiConsumer reject); default JPromise onError(Consumer consumer) { return onError((error, ctx) -> consumer.accept(error)); } JPromise onFinally(TriConsumer consumer); default JPromise onFinally(Runnable runnable) { return onFinally((v, e, ctx) -> runnable.run()); } default JPromise onFinally(Consumer runnable) { return onFinally((v, e, ctx) -> runnable.accept(ctx)); } default JPromise onFinally(BiConsumer runnable) { return onFinally((v, e, ctx) -> runnable.accept(v, e)); } void schedule(JContext context); JHandle async(JContext context); default JHandle async() { return async(JContext.defaultContext()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy