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

io.github.sinri.keel.facade.async.KeelAsyncKit Maven / Gradle / Ivy

Go to download

A website framework with VERT.X for ex-PHP-ers, exactly Ark Framework Users.

The newest version!
package io.github.sinri.keel.facade.async;

import io.github.sinri.keel.verticles.KeelVerticle;
import io.github.sinri.keel.verticles.KeelVerticleImplPure;
import io.vertx.core.*;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import static io.github.sinri.keel.facade.KeelInstance.Keel;

/**
 * @since 3.0.0
 * @since 3.0.8 changed a lot.
 */
public interface KeelAsyncKit {
    /**
     * @since 2.9.3 callFutureRepeat
     * @since 3.0.0 repeatedlyCall
     */
    static Future repeatedlyCall(@Nonnull Function> routineResultFutureFunction) {
        return FutureRepeat.call(routineResultFutureFunction);
    }

    /**
     * @since 2.9 callFutureForEach
     * @since 3.0.0 iterativelyCall
     */
    static  Future iterativelyCall(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
        return FutureForEach.call(collection, itemProcessor);
    }

    /**
     * @since 3.0.13
     */
    static  Future iterativelyCall(@Nonnull Iterator iterator, @Nonnull Function> itemProcessor) {
        return repeatedlyCall(routineResult -> {
            if (iterator.hasNext()) {
                T t = iterator.next();
                return itemProcessor.apply(t);
            } else {
                routineResult.stop();
                return Future.succeededFuture();
            }
        });
    }

    /**
     * @since 3.0.13
     */
    static  Future iterativelyBatchCall(@Nonnull Iterator iterator, @Nonnull Function, Future> itemsProcessor, int batchSize) {
        if (batchSize < 1) throw new IllegalArgumentException("BATCH SIZE IS AT LEAST 1.");
        return repeatedlyCall(routineResult -> {
            List buffer = new ArrayList<>();
            boolean hasNext = iterator.hasNext();
            while (hasNext) {
                T t = iterator.next();
                buffer.add(t);
                hasNext = iterator.hasNext();

                if (!hasNext) {
                    routineResult.stop();
                }

                if (buffer.size() >= batchSize) {
                    break;
                }
            }
            if (!buffer.isEmpty()) {
                return itemsProcessor.apply(buffer);
            } else {
                return Future.succeededFuture();
            }
        });
    }

    /**
     * @since 3.2.3
     */
    static  Future iterativelyCall(@Nonnull Iterable iterable, @Nonnull BiFunction> itemProcessor) {
        return FutureForEachBreakable.call(iterable, itemProcessor);
    }

    /**
     * @since 2.9 callFutureForRange
     * @since 3.0.0 stepwiseCall
     */
    static Future stepwiseCall(@Nonnull FutureForRange.Options options, @Nonnull Function> handleFunction) {
        return FutureForRange.call(options, handleFunction);
    }

    /**
     * @since 2.9 callFutureForRange
     * @since 3.0.0 stepwiseCall
     */
    static Future stepwiseCall(int times, @Nonnull Function> handleFunction) {
        return FutureForRange.call(times, handleFunction);
    }

    /**
     * @since 2.9 callFutureSleep
     * @since 3.0.0 sleep
     */
    static Future sleep(long t) {
        return FutureSleep.call(t);
    }

    static Future sleep(long t, @Nullable Promise interrupter) {
        return FutureSleep.call(t, interrupter);
    }

    static  Future parallelForAllSuccess(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
        return FutureForEachParallel.all(collection, itemProcessor);
    }

    static  Future parallelForAnySuccess(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
        return FutureForEachParallel.any(collection, itemProcessor);
    }

    static  Future parallelForAllComplete(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
        return FutureForEachParallel.join(collection, itemProcessor);
    }

    static  Future> parallelForAllResult(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
        return FutureForEachParallel.call(collection, itemProcessor);
    }

    /**
     * @since 3.1.0
     */
    static  Future exclusivelyCall(@Nonnull String lockName, long waitTimeForLock, @Nonnull Supplier> exclusiveSupplier) {
        return Keel.getVertx().sharedData()
                .getLockWithTimeout(lockName, waitTimeForLock)
                .compose(lock -> Future.succeededFuture()
                        .compose(v -> exclusiveSupplier.get())
                        .andThen(ar -> lock.release())
                );
    }

    /**
     * @since 3.0.11 not only Void!
     */
    static  Future exclusivelyCall(@Nonnull String lockName, @Nonnull Supplier> exclusiveSupplier) {
        return exclusivelyCall(lockName, 1000L, exclusiveSupplier);
    }

    /**
     * @param promiseHandler execute a regular job, even if it is blocking, handle method is decided by users.
     * @since 3.0.0
     */
    static void endless(@Nonnull Handler> promiseHandler) {
        Promise promise = Promise.promise();
        promiseHandler.handle(promise);
        promise.future()
                .andThen(ar -> Keel.getVertx()
                        .setTimer(1L, timerID -> endless(promiseHandler)));
    }

    /**
     * @param supplier An async job handler, results a Void Future.
     * @since 3.0.1
     */
    static void endless(@Nonnull Supplier> supplier) {
        KeelAsyncKit.repeatedlyCall(routineResult -> Future.succeededFuture()
                .compose(v -> supplier.get())
                .eventually(() -> Future.succeededFuture()));
    }

    /**
     * @since 3.0.1
     */
    static  Future vertxizedCompletableFuture(@Nonnull CompletableFuture completableFuture) {
        Promise promise = Promise.promise();
        completableFuture.whenComplete((r, t) -> {
            if (t != null) {
                promise.fail(t);
            } else {
                promise.complete(r);
            }
        });
        return promise.future();
    }

    /**
     * @since 3.0.1
     */
    static  Future vertxizedRawFuture(@Nonnull java.util.concurrent.Future rawFuture, long sleepTime) {
        return KeelAsyncKit.repeatedlyCall(routineResult -> {
                    if (rawFuture.isDone() || rawFuture.isCancelled()) {
                        routineResult.stop();
                    }
                    return sleep(sleepTime);
                })
                .compose(slept -> {
                    try {
                        return Future.succeededFuture(rawFuture.get());
                    } catch (InterruptedException | ExecutionException e) {
                        return Future.failedFuture(e);
                    }
                });
    }

    /**
     * @since 3.0.10 Technical Preview: instead of Vertx::executeBlocking(Handler<Promise<T>> blockingCodeHandler)
     * @since 3.0.18 Finished Technical Preview.
     */
    @Nonnull
    static  Future executeBlocking(@Nonnull Handler> blockingCodeHandler) {
        Promise promise = Promise.promise();
        KeelVerticle verticle = new KeelVerticleImplPure() {

            @Override
            protected void startAsPureKeelVerticle() {
                blockingCodeHandler.handle(promise);
                promise.future().onComplete(ar -> this.undeployMe());
            }
        };
        return verticle.deployMe(new DeploymentOptions().setThreadingModel(ThreadingModel.WORKER))
                .compose(deploymentId -> promise.future());
    }

    /**
     * @since 3.2.19
     */
    static  CompletableFuture createPseudoAwaitCompletableFuture(Handler> blockingCodeHandler) {
        CompletableFuture completableFuture = new CompletableFuture<>();
        executeBlocking(blockingCodeHandler)
                .andThen(ar -> {
                    if (ar.succeeded()) {
                        completableFuture.complete(ar.result());
                    } else {
                        completableFuture.completeExceptionally(ar.cause());
                    }
                });
        return completableFuture;
    }

    /**
     * @since 3.2.19
     */
    static  T pseudoAwait(Handler> blockingCodeHandler) {
        CompletableFuture completableFuture = createPseudoAwaitCompletableFuture(blockingCodeHandler);
        try {
            return completableFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy