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

net.lulihu.promise.Promise Maven / Gradle / Ivy

package net.lulihu.promise;

import net.lulihu.ObjectKit.StrKit;

import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 誓言
 *
 * @param 
 */
public class Promise implements Future {

    /**
     * 事件
     *
     * @param  入参
     */
    public interface Action {
        void invoke(T result);
    }

    // 任务锁
    private final CountDownLatch taskLock = new CountDownLatch(1);
    // 绑定回调
    private List>> callbacks = new ArrayList<>();
    // 返回参数
    private V result = null;
    // 异常
    protected Throwable exception = null;
    // 是否已经执行完成
    private boolean invoked = false;

    public boolean cancel(boolean mayInterruptIfRunning) {
        return false;
    }

    public boolean isCancelled() {
        return false;
    }

    public boolean isDone() {
        return invoked;
    }

    /**
     * 获取结果
     * 

* 该方法立即返回,如果还未产生结果至则返回null * * @return 返回处理结果或者null */ public V getOrNull() { return result; } /** * 获取处理结果 *

* 该方法会阻塞直到产生结果值或者被中断抛出例外 * * @return 返回处理结果 * @throws InterruptedException 在处理过程中被中断抛出 * @throws ExecutionException 执行过程中出现例外抛出 */ public V get() throws InterruptedException, ExecutionException { taskLock.await(); if (exception != null) { // 结果是一个例外 - 抛出它 throw new ExecutionException(exception); } return result; } /** * 在指定时间内获取处理结果 *

* 该方法会阻塞指定长度的时间,如果在指定时间内返回处理结果则返回,如果没有返回结果则抛出超时例外 * * @param timeout 时间 * @param unit 单位 * @return 处理结果 * @throws InterruptedException 在处理过程中被中断抛出 * @throws ExecutionException 执行过程中出现例外抛出 * @throws TimeoutException 指定时间内未能返回处理结果则抛出 */ public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { if (!taskLock.await(timeout, unit)) { throw new TimeoutException(StrKit.format("承诺在 {} {} 未能做到", timeout, unit)); } if (exception != null) { // 结果是一个例外 - 抛出它 throw new ExecutionException(exception); } return result; } /** * 结果 * * @param result 结果 */ void invoke(V result) { invokeWithResultOrException(result, null); } /** * 例外 * * @param t 例外 */ void invokeWithException(Throwable t) { invokeWithResultOrException(null, t); } private void invokeWithResultOrException(V result, Throwable t) { synchronized (this) { if (invoked) return; invoked = true; this.result = result; this.exception = t; taskLock.countDown(); } // 执行结束 执行回调 for (Action> callback : callbacks) { callback.invoke(this); } } /** * 增加承诺 *

* 如果当前承诺正在实现过程中则直接执行否则添加到回调 * * @param callback 回调 */ public void onRedeem(Action> callback) { synchronized (this) { if (!invoked) { callbacks.add(callback); } } if (invoked) { callback.invoke(this); } } /** * 等待所有承诺完成 再返回 * * @param promises 承诺s * @param 泛型 * @return {@linkplain Promise} */ public static Promise> waitAll(final Promise... promises) { return waitAll(Arrays.asList(promises)); } /** * 等待所有承诺完成 在返回 * * @param promises 承诺s * @param 泛型 * @return {@linkplain Promise} */ public static Promise> waitAll(final Collection> promises) { final CountDownLatch waitAllLock = new CountDownLatch(promises.size()); final Promise> result = new Promise>() { @Override public boolean cancel(boolean mayInterruptIfRunning) { boolean r = true; for (Promise f : promises) { r = r & f.cancel(mayInterruptIfRunning); } return r; } @Override public boolean isCancelled() { boolean r = true; for (Promise f : promises) { r = r & f.isCancelled(); } return r; } @Override public boolean isDone() { boolean r = true; for (Promise f : promises) { r = r & f.isDone(); } return r; } @Override public List get() throws InterruptedException, ExecutionException { waitAllLock.await(); List r = new ArrayList<>(); for (Promise f : promises) { r.add(f.get()); } return r; } @Override public List get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { if (!waitAllLock.await(timeout, unit)) { throw new TimeoutException(String.format("Promises didn't redeem in %s %s", timeout, unit)); } return get(); } }; final Action> action = completed -> { waitAllLock.countDown(); if (waitAllLock.getCount() == 0) { try { result.invoke(result.get()); } catch (Exception e) { result.invokeWithException(e); } } }; if (promises.isEmpty()) { result.invoke(Collections.emptyList()); } else { for (Promise f : promises) { f.onRedeem(action); } } return result; } /** * 使用誓言对象 * * @param v 参数 * @param 入参类型 * @return 返回一个包装入参的誓言对象 */ public static Promise pure(final V v) { Promise p = new Promise<>(); p.invoke(v); return p; } /** * 使用誓言对象 * * @param t 异常 * @param v * @return 返回一个包装指定异常的誓言对象 */ public static Promise wrap(final Throwable t) { Promise p = new Promise<>(); p.invokeWithException(t); return p; } /** * 在原有的誓言流程上继续绑定誓言 * * @param function 誓言转换函数 * @param 绑定誓言的类型 * @return 绑定后的誓言对象 */ public Promise bind(final Function> function) { Promise result = new Promise<>(); this.onRedeem(callback -> { try { V v = callback.get(); Promise applicationResult = function.apply(v); applicationResult.onRedeem(applicationCallback -> { try { R r = applicationCallback.get(); result.invoke(r); } catch (Throwable e) { result.invokeWithException(e); } }); } catch (Throwable e) { result.invokeWithException(e); } }); return result; } /** * 使用方式 *

* Promise apply = Promise.fmap((Function) i -> i + "-").apply(Promise.pure(10)); * * @param function 处理表达式 * @param 入参 * @param 出参 * @return {@linkplain Function} */ public static Function, Promise> fmap(Function function) { return p -> { Promise result = new Promise<>(); p.onRedeem(callback -> { try { T t = callback.get(); R r = function.apply(t); result.invoke(r); } catch (Throwable e) { result.invokeWithException(e); } }); return result; }; } /** * 加入多个方式 * * @param promise 誓言 * @param 入参类型 * @return {@linkplain Promise} */ public static Promise join(Promise> promise) { Promise result = new Promise<>(); promise.onRedeem(callback -> { try { Promise inner = callback.get(); inner.onRedeem(innerCallback -> { try { T t = innerCallback.get(); result.invoke(t); } catch (InterruptedException | ExecutionException e) { result.invokeWithException(e); } }); } catch (InterruptedException | ExecutionException e) { result.invokeWithException(e); } }); return result; } /** * 使用方式 *

* Promise promise = Promise.lift((Function) i -> i++).apply(10); * * @param function 表达式 * @param 入参类型 * @param 返回参数 * @return {@linkplain Function} */ public static Function> lift(Function function) { return function.andThen(Promise::pure); } /** * 使用方式 *

* Promise.lift((Consumer) System.out::println).apply(10); * * @param consumer 无返回参数表达式 * @param 入参类型 * @return void的誓言 */ public static Function> lift(Consumer consumer) { return t -> { consumer.accept(t); return Promise.pure((Void) null); }; } }