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

tech.ytsaurus.client.RpcClientSlot Maven / Gradle / Ivy

The newest version!
package tech.ytsaurus.client;

import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.ytsaurus.client.rpc.RpcClient;
import tech.ytsaurus.core.common.YTsaurusError;

class RpcClientSlot implements AutoCloseable {
    private static final Logger logger = LoggerFactory.getLogger(RpcClientSlot.class);

    private final AtomicBoolean seemsBroken;
    private final CompletableFuture client;
    private HostPort address;

    RpcClientSlot() {
        this.seemsBroken = new AtomicBoolean(false);
        this.client = new CompletableFuture<>();
    }

    public Optional getClient(Duration timeout) {
        try {
            return Optional.of(client.get(timeout.toMillis(), TimeUnit.MILLISECONDS));
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Failed to get client from slot ", e);
        } catch (TimeoutException e) {
            return Optional.empty();
        }
    }

    public RpcClient getClient() {
        try {
            return client.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Failed to get client from slot ", e);
        }
    }

    public Optional getOrCompleteClient() {
        client.completeExceptionally(new Exception("RpcClientSlot is closed"));
        if (client.isDone() && !client.isCompletedExceptionally()) {
            return Optional.of(getClient());
        }
        return Optional.empty();
    }

    @Override
    public void close() {
        Optional maybeClient = getOrCompleteClient();
        maybeClient.ifPresent(this::closeClient);
    }

    CompletableFuture getClientFuture() {
        return client;
    }

    void setClient(RpcClient client, HostPort address) {
        RpcClient failureDetectingClient = new FailureDetectingRpcClient(
                client,
                YTsaurusError::isUnrecoverable,
                (e) -> setSeemsBroken()
        );
        this.address = address;
        this.client.complete(failureDetectingClient);
    }

    boolean seemsBroken() {
        return seemsBroken.get();
    }

    private void setSeemsBroken() {
        seemsBroken.set(true);
        logger.info("Channel `{}` seems broken", client.getNow(null));
    }

    HostPort getAddress() {
        return address;
    }

    boolean isClientDone() {
        return client.isDone();
    }

    private void closeClient(RpcClient client) {
        try {
            client.close();
        } catch (Exception e) {
            logger.error(e.getMessage(), "Error while terminating channel pool");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy