Search in sources :

Example 1 with ConnectionKey

use of io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey in project lettuce-core by lettuce-io.

the class PooledClusterConnectionProvider method getWriteConnection.

private CompletableFuture<StatefulRedisConnection<K, V>> getWriteConnection(int slot) {
    // avoid races when reconfiguring partitions.
    CompletableFuture<StatefulRedisConnection<K, V>> writer;
    synchronized (stateLock) {
        writer = writers[slot];
    }
    if (writer == null) {
        RedisClusterNode partition = partitions.getPartitionBySlot(slot);
        if (partition == null) {
            clusterEventListener.onUncoveredSlot(slot);
            return Futures.failed(new PartitionSelectorException("Cannot determine a partition for slot " + slot + ".", partitions.clone()));
        }
        // Use always host and port for slot-oriented operations. We don't want to get reconnected on a different
        // host because the nodeId can be handled by a different host.
        RedisURI uri = partition.getUri();
        ConnectionKey key = new ConnectionKey(Intent.WRITE, uri.getHost(), uri.getPort());
        ConnectionFuture<StatefulRedisConnection<K, V>> future = getConnectionAsync(key);
        return future.thenApply(connection -> {
            synchronized (stateLock) {
                if (writers[slot] == null) {
                    writers[slot] = CompletableFuture.completedFuture(connection);
                }
            }
            return connection;
        }).toCompletableFuture();
    }
    return writer;
}
Also used : Arrays(java.util.Arrays) Partitions(io.lettuce.core.cluster.models.partitions.Partitions) CompletableFuture(java.util.concurrent.CompletableFuture) StatefulConnection(io.lettuce.core.api.StatefulConnection) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) Function(java.util.function.Function) RedisChannelWriter(io.lettuce.core.RedisChannelWriter) ConnectionKey(io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey) Futures(io.lettuce.core.internal.Futures) ArrayList(java.util.ArrayList) LettuceAssert(io.lettuce.core.internal.LettuceAssert) OrderingReadFromAccessor(io.lettuce.core.OrderingReadFromAccessor) StatefulRedisConnection(io.lettuce.core.api.StatefulRedisConnection) PushMessage(io.lettuce.core.api.push.PushMessage) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) RedisFuture(io.lettuce.core.RedisFuture) AsyncConnectionProvider(io.lettuce.core.internal.AsyncConnectionProvider) Iterator(java.util.Iterator) RedisException(io.lettuce.core.RedisException) RedisClusterNode(io.lettuce.core.cluster.models.partitions.RedisClusterNode) Exceptions(io.lettuce.core.internal.Exceptions) Collection(java.util.Collection) RedisClusterPushListener(io.lettuce.core.cluster.api.push.RedisClusterPushListener) CompletionException(java.util.concurrent.CompletionException) Collectors(java.util.stream.Collectors) RedisCodec(io.lettuce.core.codec.RedisCodec) RedisURI(io.lettuce.core.RedisURI) List(java.util.List) RedisConnectionException(io.lettuce.core.RedisConnectionException) HostAndPort(io.lettuce.core.internal.HostAndPort) ReadFrom(io.lettuce.core.ReadFrom) InternalLogger(io.netty.util.internal.logging.InternalLogger) ConnectionFuture(io.lettuce.core.ConnectionFuture) InternalLoggerFactory(io.netty.util.internal.logging.InternalLoggerFactory) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) RedisClusterNode(io.lettuce.core.cluster.models.partitions.RedisClusterNode) RedisURI(io.lettuce.core.RedisURI) ConnectionKey(io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey) StatefulRedisConnection(io.lettuce.core.api.StatefulRedisConnection)

Example 2 with ConnectionKey

use of io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey in project lettuce-core by lettuce-io.

the class PooledClusterConnectionProvider method getReadFromConnections.

private CompletableFuture<StatefulRedisConnection<K, V>>[] getReadFromConnections(List<RedisNodeDescription> selection) {
    // Use always host and port for slot-oriented operations. We don't want to get reconnected on a different
    // host because the nodeId can be handled by a different host.
    CompletableFuture<StatefulRedisConnection<K, V>>[] readerCandidates = new CompletableFuture[selection.size()];
    for (int i = 0; i < selection.size(); i++) {
        RedisNodeDescription redisClusterNode = selection.get(i);
        RedisURI uri = redisClusterNode.getUri();
        ConnectionKey key = new ConnectionKey(redisClusterNode.getRole().isUpstream() ? Intent.WRITE : Intent.READ, uri.getHost(), uri.getPort());
        readerCandidates[i] = getConnectionAsync(key).toCompletableFuture();
    }
    return readerCandidates;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) RedisURI(io.lettuce.core.RedisURI) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) ConnectionKey(io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey)

Example 3 with ConnectionKey

use of io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey in project lettuce-core by lettuce-io.

the class AsyncConnectionProviderIntegrationTests method before.

@BeforeEach
void before() throws Exception {
    serverSocket = new ServerSocket(9393, 1);
    client = RedisClusterClient.create(resources, "redis://localhost");
    client.setOptions(ClusterClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build());
    sut = new AsyncConnectionProvider<>(new AbstractClusterNodeConnectionFactory<String, String>(resources) {

        @Override
        public ConnectionFuture<StatefulRedisConnection<String, String>> apply(ConnectionKey connectionKey) {
            RedisURI redisURI = RedisURI.create(TestSettings.host(), serverSocket.getLocalPort());
            redisURI.setTimeout(Duration.ofSeconds(5));
            ConnectionFuture<StatefulRedisConnection<String, String>> future = client.connectToNodeAsync(StringCodec.UTF8, "", null, Mono.just(new InetSocketAddress(connectionKey.host, serverSocket.getLocalPort())));
            connectInitiated.countDown();
            return future;
        }
    });
}
Also used : RedisURI(io.lettuce.core.RedisURI) InetSocketAddress(java.net.InetSocketAddress) ConnectionKey(io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey) ServerSocket(java.net.ServerSocket) StatefulRedisConnection(io.lettuce.core.api.StatefulRedisConnection) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 4 with ConnectionKey

use of io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey in project lettuce-core by lettuce-io.

the class AsyncConnectionProviderIntegrationTests method shouldCloseConnectionByKey.

@Test
void shouldCloseConnectionByKey() throws IOException {
    ConnectionKey connectionKey = new ConnectionKey(ClusterConnectionProvider.Intent.READ, TestSettings.host(), TestSettings.port());
    sut.getConnection(connectionKey);
    sut.close(connectionKey);
    assertThat(sut.getConnectionCount()).isEqualTo(0);
    sut.close();
    serverSocket.accept();
}
Also used : ConnectionKey(io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey) Test(org.junit.jupiter.api.Test)

Example 5 with ConnectionKey

use of io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey in project lettuce-core by lettuce-io.

the class AsyncConnectionProviderIntegrationTests method connectShouldFail.

@Test
void connectShouldFail() throws Exception {
    Socket socket = new Socket(TestSettings.host(), serverSocket.getLocalPort());
    ClusterClientOptions clientOptions = ClusterClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).socketOptions(SocketOptions.builder().connectTimeout(1, TimeUnit.SECONDS).build()).build();
    client.setOptions(clientOptions);
    ConnectionKey connectionKey = new ConnectionKey(ClusterConnectionProvider.Intent.READ, "8.8.8.8", TestSettings.port());
    StopWatch stopWatch = new StopWatch();
    assertThatThrownBy(() -> TestFutures.awaitOrTimeout(sut.getConnection(connectionKey))).hasCauseInstanceOf(ConnectTimeoutException.class);
    stopWatch.start();
    assertThatThrownBy(() -> TestFutures.awaitOrTimeout(sut.getConnection(connectionKey))).hasCauseInstanceOf(ConnectTimeoutException.class);
    stopWatch.stop();
    assertThat(TimeUnit.NANOSECONDS.toMillis(stopWatch.getNanoTime())).isBetween(0L, 1200L);
    sut.close();
    socket.close();
}
Also used : ConnectionKey(io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey) Socket(java.net.Socket) ServerSocket(java.net.ServerSocket) StopWatch(org.apache.commons.lang3.time.StopWatch) Test(org.junit.jupiter.api.Test)

Aggregations

ConnectionKey (io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey)7 Test (org.junit.jupiter.api.Test)4 RedisURI (io.lettuce.core.RedisURI)3 ServerSocket (java.net.ServerSocket)3 StatefulRedisConnection (io.lettuce.core.api.StatefulRedisConnection)2 RedisNodeDescription (io.lettuce.core.models.role.RedisNodeDescription)2 Socket (java.net.Socket)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 StopWatch (org.apache.commons.lang3.time.StopWatch)2 ConnectionFuture (io.lettuce.core.ConnectionFuture)1 OrderingReadFromAccessor (io.lettuce.core.OrderingReadFromAccessor)1 ReadFrom (io.lettuce.core.ReadFrom)1 RedisChannelWriter (io.lettuce.core.RedisChannelWriter)1 RedisConnectionException (io.lettuce.core.RedisConnectionException)1 RedisException (io.lettuce.core.RedisException)1 RedisFuture (io.lettuce.core.RedisFuture)1 StatefulConnection (io.lettuce.core.api.StatefulConnection)1 PushMessage (io.lettuce.core.api.push.PushMessage)1 RedisClusterPushListener (io.lettuce.core.cluster.api.push.RedisClusterPushListener)1 Partitions (io.lettuce.core.cluster.models.partitions.Partitions)1