io.tarantool.driver.core.connection.AbstractTarantoolConnectionManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cartridge-driver Show documentation
Show all versions of cartridge-driver Show documentation
Tarantool Cartridge driver for Tarantool versions 1.10+ based on Netty framework
package io.tarantool.driver.core.connection;
import io.tarantool.driver.api.TarantoolClientConfig;
import io.tarantool.driver.api.TarantoolServerAddress;
import io.tarantool.driver.api.connection.ConnectionSelectionStrategy;
import io.tarantool.driver.api.connection.ConnectionSelectionStrategyFactory;
import io.tarantool.driver.api.connection.TarantoolConnection;
import io.tarantool.driver.api.connection.TarantoolConnectionListeners;
import io.tarantool.driver.exceptions.NoAvailableConnectionsException;
import io.tarantool.driver.exceptions.TarantoolClientException;
import io.tarantool.driver.exceptions.TarantoolConnectionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.Phaser;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
* Contains basic connection establishing and selection strategy invocation algorithms. Subclasses must implement
* the retrieving of Tarantool server addresses.
*
* @author Alexey Kuzin
*/
public abstract class AbstractTarantoolConnectionManager implements TarantoolConnectionManager {
private final TarantoolClientConfig config;
private final TarantoolConnectionFactory connectionFactory;
private final ConnectionSelectionStrategyFactory selectStrategyFactory;
private final TarantoolConnectionListeners connectionListeners;
private Map> connectionRegistry;
private final AtomicReference connectionSelectStrategy = new AtomicReference<>();
// connection init sequence state
private final AtomicReference connectionMode = new AtomicReference<>(ConnectionMode.FULL);
// resettable barrier for preventing multiple threads from running into the connection init sequence
private final Phaser initPhaser = new Phaser(0);
private static final Logger logger = LoggerFactory.getLogger(AbstractTarantoolConnectionManager.class);
/**
* Basic constructor
*
* @param config Tarantool client config
* @param connectionFactory connection factory
* @param connectionListeners connection listeners
*/
public AbstractTarantoolConnectionManager(
TarantoolClientConfig config,
TarantoolConnectionFactory connectionFactory,
TarantoolConnectionListeners connectionListeners) {
this.config = config;
this.connectionFactory = connectionFactory;
this.selectStrategyFactory = config.getConnectionSelectionStrategyFactory();
this.connectionSelectStrategy.set(selectStrategyFactory.create(config, Collections.emptyList()));
this.connectionListeners = connectionListeners;
this.connectionRegistry = new HashMap<>();
}
/**
* Get server addresses to connect to. They must belong to one cluster and contain the information necessary for
* the internal {@link ConnectionSelectionStrategy} instance.
*
* @return Tarantool server addresses
*/
protected abstract Collection getAddresses();
@Override
public CompletableFuture getConnection() {
return getConnectionInternal().handle((connection, ex) -> {
if (ex != null) {
if (ex instanceof CompletionException) {
ex = ex.getCause();
}
if (ex instanceof NoAvailableConnectionsException) {
connectionMode.compareAndSet(ConnectionMode.OFF, ConnectionMode.FULL);
}
throw new TarantoolConnectionException(ex);
}
return connection;
});
}
@Override
public boolean refresh() {
return connectionMode.compareAndSet(ConnectionMode.OFF, ConnectionMode.PARTIAL);
}
private CompletableFuture getConnectionInternal() {
CompletableFuture result;
ConnectionMode currentMode = connectionMode.get();
if (initPhaser.getRegisteredParties() == 0 &&
(connectionMode.compareAndSet(ConnectionMode.FULL, ConnectionMode.IN_PROGRESS) ||
connectionMode.compareAndSet(ConnectionMode.PARTIAL, ConnectionMode.IN_PROGRESS))) {
AtomicReference
© 2015 - 2025 Weber Informatics LLC | Privacy Policy