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

com.tencent.polaris.api.rpc.InstancesFuture Maven / Gradle / Ivy

The newest version!
/*
 * Tencent is pleased to support the open source community by making polaris-java available.
 *
 * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * Unless required by applicable law or agreed to in writing, software distributed
 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package com.tencent.polaris.api.rpc;

import com.tencent.polaris.metadata.core.manager.MetadataContextHolder;
import com.tencent.polaris.threadlocal.cross.ExecutorWrapper;

import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 异步获取实例的应答
 */
public class InstancesFuture implements Future, CompletionStage {

    private final CompletableFuture completableFuture;

    private static final boolean USE_COMMON_POOL =
            (ForkJoinPool.getCommonPoolParallelism() > 1);

    /**
     * Default executor -- ForkJoinPool.commonPool() unless it cannot
     * support parallelism.
     */
    private static final Executor ASYNC_POOL = USE_COMMON_POOL ?
            ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

    static final class ThreadPerTaskExecutor implements Executor {
        public void execute(Runnable r) {
            Objects.requireNonNull(r);
            new Thread(r).start();
        }
    }

    public InstancesFuture(Supplier supplier) {
        this.completableFuture = CompletableFuture.supplyAsync(supplier, wrapExecutor(ASYNC_POOL));
    }

    @Override
    public  CompletionStage thenApply(Function fn) {
        return completableFuture.thenApply(fn);
    }

    @Override
    public  CompletionStage thenApplyAsync(Function fn) {
        return completableFuture.thenApplyAsync(fn, wrapExecutor(defaultExecutor()));
    }

    @Override
    public  CompletionStage thenApplyAsync(Function fn,
                                                 Executor executor) {
        return completableFuture.thenApplyAsync(fn, wrapExecutor(executor));
    }

    @Override
    public CompletionStage thenAccept(Consumer action) {
        return completableFuture.thenAccept(action);
    }

    @Override
    public CompletionStage thenAcceptAsync(Consumer action) {
        return completableFuture.thenAcceptAsync(action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public CompletionStage thenAcceptAsync(Consumer action, Executor executor) {
        return completableFuture.thenAcceptAsync(action, wrapExecutor(executor));
    }

    @Override
    public CompletionStage thenRun(Runnable action) {
        return completableFuture.thenRun(action);
    }

    @Override
    public CompletionStage thenRunAsync(Runnable action) {
        return completableFuture.thenRunAsync(action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public CompletionStage thenRunAsync(Runnable action, Executor executor) {
        return completableFuture.thenRunAsync(action, wrapExecutor(executor));
    }

    @Override
    public  CompletionStage thenCombine(CompletionStage other,
                                                 BiFunction fn) {
        return completableFuture.thenCombine(other, fn);
    }

    @Override
    public  CompletionStage thenCombineAsync(CompletionStage other,
                                                      BiFunction fn) {
        return completableFuture.thenCombineAsync(other, fn, wrapExecutor(defaultExecutor()));
    }

    @Override
    public  CompletionStage thenCombineAsync(CompletionStage other,
                                                      BiFunction fn, Executor executor) {
        return completableFuture.thenCombineAsync(other, fn, wrapExecutor(executor));
    }

    @Override
    public  CompletionStage thenAcceptBoth(CompletionStage other,
                                                    BiConsumer action) {
        return completableFuture.thenAcceptBoth(other, action);
    }

    @Override
    public  CompletionStage thenAcceptBothAsync(CompletionStage other,
                                                         BiConsumer action) {
        return completableFuture.thenAcceptBothAsync(other, action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public  CompletionStage thenAcceptBothAsync(CompletionStage other,
                                                         BiConsumer action,
                                                         Executor executor) {
        return completableFuture.thenAcceptBothAsync(other, action, wrapExecutor(executor));
    }

    @Override
    public CompletionStage runAfterBoth(CompletionStage other, Runnable action) {
        return completableFuture.runAfterBoth(other, action);
    }

    @Override
    public CompletionStage runAfterBothAsync(CompletionStage other, Runnable action) {
        return completableFuture.runAfterBothAsync(other, action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public CompletionStage runAfterBothAsync(CompletionStage other, Runnable action, Executor executor) {
        return completableFuture.runAfterBothAsync(other, action, wrapExecutor(executor));
    }

    @Override
    public  CompletionStage applyToEither(CompletionStage other,
                                                Function fn) {
        return completableFuture.applyToEither(other, fn);
    }

    @Override
    public  CompletionStage applyToEitherAsync(CompletionStage other,
                                                     Function fn) {
        return completableFuture.applyToEitherAsync(other, fn, wrapExecutor(defaultExecutor()));
    }

    @Override
    public  CompletionStage applyToEitherAsync(CompletionStage other,
                                                     Function fn, Executor executor) {
        return completableFuture.applyToEitherAsync(other, fn, wrapExecutor(executor));
    }

    @Override
    public CompletionStage acceptEither(CompletionStage other,
                                              Consumer action) {
        return completableFuture.acceptEither(other, action);
    }

    @Override
    public CompletionStage acceptEitherAsync(CompletionStage other,
                                                   Consumer action) {
        return completableFuture.acceptEitherAsync(other, action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public CompletionStage acceptEitherAsync(CompletionStage other,
                                                   Consumer action, Executor executor) {
        return completableFuture.acceptEitherAsync(other, action, wrapExecutor(executor));
    }

    @Override
    public CompletionStage runAfterEither(CompletionStage other, Runnable action) {
        return completableFuture.runAfterEither(other, action);
    }

    @Override
    public CompletionStage runAfterEitherAsync(CompletionStage other, Runnable action) {
        return completableFuture.runAfterEitherAsync(other, action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public CompletionStage runAfterEitherAsync(CompletionStage other, Runnable action, Executor executor) {
        return completableFuture.runAfterEitherAsync(other, action, wrapExecutor(executor));
    }

    @Override
    public  CompletionStage thenCompose(Function> fn) {
        return completableFuture.thenCompose(fn);
    }

    @Override
    public  CompletionStage thenComposeAsync(
            Function> fn) {
        return completableFuture.thenComposeAsync(fn, wrapExecutor(defaultExecutor()));
    }

    @Override
    public  CompletionStage thenComposeAsync(Function> fn,
                                                   Executor executor) {
        return completableFuture.thenComposeAsync(fn, wrapExecutor(executor));
    }

    @Override
    public CompletionStage exceptionally(Function fn) {
        return completableFuture.exceptionally(fn);
    }

    @Override
    public CompletionStage whenComplete(
            BiConsumer action) {
        return completableFuture.whenComplete(action);
    }

    @Override
    public CompletionStage whenCompleteAsync(
            BiConsumer action) {
        return completableFuture.whenCompleteAsync(action, wrapExecutor(defaultExecutor()));
    }

    @Override
    public CompletionStage whenCompleteAsync(
            BiConsumer action, Executor executor) {
        return completableFuture.whenCompleteAsync(action, wrapExecutor(executor));
    }

    @Override
    public  CompletionStage handle(BiFunction fn) {
        return completableFuture.handle(fn);
    }

    @Override
    public  CompletionStage handleAsync(BiFunction fn) {
        return completableFuture.handleAsync(fn, wrapExecutor(defaultExecutor()));
    }

    @Override
    public  CompletionStage handleAsync(BiFunction fn,
                                              Executor executor) {
        return completableFuture.handleAsync(fn, wrapExecutor(executor));
    }

    @Override
    public CompletableFuture toCompletableFuture() {
        return completableFuture.toCompletableFuture();
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return completableFuture.cancel(mayInterruptIfRunning);
    }

    @Override
    public boolean isCancelled() {
        return completableFuture.isCancelled();
    }

    @Override
    public boolean isDone() {
        return completableFuture.isDone();
    }

    @Override
    public InstancesResponse get() throws InterruptedException, ExecutionException {
        return completableFuture.get();
    }

    @Override
    public InstancesResponse get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException {
        return completableFuture.get(timeout, unit);
    }

    private Executor wrapExecutor(Executor executor) {
        return new ExecutorWrapper<>(executor, MetadataContextHolder::getOrCreate, MetadataContextHolder::set);
    }

    private Executor defaultExecutor() {
        return ASYNC_POOL;
    }
}