Search in sources :

Example 16 with RedisNodeDescription

use of io.lettuce.core.models.role.RedisNodeDescription in project lettuce-core by lettuce-io.

the class Requests method onEmit.

@Override
protected void onEmit(Emission<List<RedisNodeDescription>> emission) {
    List<RedisNodeDescription> result = new ArrayList<>();
    Map<RedisNodeDescription, Long> latencies = new HashMap<>();
    for (RedisNodeDescription node : nodes) {
        TimedAsyncCommand<String, String, String> future = getRequest(node.getUri());
        if (future == null || !future.isDone()) {
            continue;
        }
        RedisNodeDescription redisNodeDescription = findNodeByUri(nodes, node.getUri());
        latencies.put(redisNodeDescription, future.duration());
        result.add(redisNodeDescription);
    }
    SortAction sortAction = SortAction.getSortAction();
    sortAction.sort(result, new LatencyComparator(latencies));
    emission.success(result);
}
Also used : LatencyComparator(io.lettuce.core.masterreplica.TopologyComparators.LatencyComparator) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) SortAction(io.lettuce.core.masterreplica.TopologyComparators.SortAction)

Example 17 with RedisNodeDescription

use of io.lettuce.core.models.role.RedisNodeDescription in project lettuce-core by lettuce-io.

the class MasterReplicaTopologyRefresh method getConnections.

/*
     * Establish connections asynchronously.
     */
private AsyncConnections getConnections(Iterable<RedisNodeDescription> nodes) {
    List<RedisNodeDescription> nodeList = LettuceLists.newList(nodes);
    AsyncConnections connections = new AsyncConnections(nodeList);
    for (RedisNodeDescription node : nodeList) {
        RedisURI redisURI = node.getUri();
        String message = String.format("Unable to connect to %s", redisURI);
        try {
            CompletableFuture<StatefulRedisConnection<String, String>> connectionFuture = nodeConnectionFactory.connectToNodeAsync(CODEC, redisURI);
            CompletableFuture<StatefulRedisConnection<String, String>> sync = new CompletableFuture<>();
            connectionFuture.whenComplete((connection, throwable) -> {
                if (throwable != null) {
                    if (throwable instanceof RedisConnectionException) {
                        if (logger.isDebugEnabled()) {
                            logger.debug(throwable.getMessage(), throwable);
                        } else {
                            logger.warn(throwable.getMessage());
                        }
                    } else {
                        logger.warn(message, throwable);
                    }
                    sync.completeExceptionally(new RedisConnectionException(message, throwable));
                } else {
                    connection.async().clientSetname("lettuce#MasterReplicaTopologyRefresh");
                    sync.complete(connection);
                }
            });
            connections.addConnection(redisURI, sync);
        } catch (RuntimeException e) {
            logger.warn(String.format(message, redisURI), e);
        }
    }
    return connections;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) RedisURI(io.lettuce.core.RedisURI) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) RedisConnectionException(io.lettuce.core.RedisConnectionException) StatefulRedisConnection(io.lettuce.core.api.StatefulRedisConnection)

Example 18 with RedisNodeDescription

use of io.lettuce.core.models.role.RedisNodeDescription in project LinkAgent by shulieTech.

the class SentinelConnectorInterceptor method doBefore.

@Override
public void doBefore(Advice advice) throws Throwable {
    Object[] arrs = advice.getParameterArray();
    try {
        List<RedisNodeDescription> lists = (List<RedisNodeDescription>) arrs[4];
        for (RedisNodeDescription nodeDescription : lists) {
            RedisURI uri = nodeDescription.getUri();
            LettuceUtils.cacheMasterSlave(uri);
        }
    } catch (Throwable t) {
    }
}
Also used : RedisURI(io.lettuce.core.RedisURI) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) List(java.util.List)

Example 19 with RedisNodeDescription

use of io.lettuce.core.models.role.RedisNodeDescription in project lettuce-core by lettuce-io.

the class PooledClusterConnectionProvider method getReadConnection.

private CompletableFuture<StatefulRedisConnection<K, V>> getReadConnection(int slot) {
    // avoid races when reconfiguring partitions.
    CompletableFuture<StatefulRedisConnection<K, V>>[] readerCandidates;
    boolean cached = true;
    synchronized (stateLock) {
        readerCandidates = readers[slot];
    }
    if (readerCandidates == null) {
        RedisClusterNode upstream = partitions.getPartitionBySlot(slot);
        if (upstream == null) {
            clusterEventListener.onUncoveredSlot(slot);
            return Futures.failed(new PartitionSelectorException(String.format("Cannot determine a partition to read for slot %d.", slot), partitions.clone()));
        }
        List<RedisNodeDescription> candidates = getReadCandidates(upstream);
        List<RedisNodeDescription> selection = readFrom.select(new ReadFrom.Nodes() {

            @Override
            public List<RedisNodeDescription> getNodes() {
                return candidates;
            }

            @Override
            public Iterator<RedisNodeDescription> iterator() {
                return candidates.iterator();
            }
        });
        if (selection.isEmpty()) {
            clusterEventListener.onUncoveredSlot(slot);
            return Futures.failed(new PartitionSelectorException(String.format("Cannot determine a partition to read for slot %d with setting %s.", slot, readFrom), partitions.clone()));
        }
        readerCandidates = getReadFromConnections(selection);
        cached = false;
    }
    CompletableFuture<StatefulRedisConnection<K, V>>[] selectedReaderCandidates = readerCandidates;
    if (cached) {
        return CompletableFuture.allOf(readerCandidates).thenCompose(v -> {
            boolean orderSensitive = isOrderSensitive(selectedReaderCandidates);
            if (!orderSensitive) {
                CompletableFuture<StatefulRedisConnection<K, V>> candidate = findRandomActiveConnection(selectedReaderCandidates, Function.identity());
                if (candidate != null) {
                    return candidate;
                }
            }
            for (CompletableFuture<StatefulRedisConnection<K, V>> candidate : selectedReaderCandidates) {
                if (candidate.join().isOpen()) {
                    return candidate;
                }
            }
            return selectedReaderCandidates[0];
        });
    }
    CompletableFuture<StatefulRedisConnection<K, V>[]> filteredReaderCandidates = new CompletableFuture<>();
    CompletableFuture.allOf(readerCandidates).thenApply(v -> selectedReaderCandidates).whenComplete((candidates, throwable) -> {
        if (throwable == null) {
            filteredReaderCandidates.complete(getConnections(candidates));
            return;
        }
        StatefulRedisConnection<K, V>[] connections = getConnections(selectedReaderCandidates);
        if (connections.length == 0) {
            filteredReaderCandidates.completeExceptionally(throwable);
            return;
        }
        filteredReaderCandidates.complete(connections);
    });
    return filteredReaderCandidates.thenApply(statefulRedisConnections -> {
        boolean orderSensitive = isOrderSensitive(statefulRedisConnections);
        CompletableFuture<StatefulRedisConnection<K, V>>[] toCache = new CompletableFuture[statefulRedisConnections.length];
        for (int i = 0; i < toCache.length; i++) {
            toCache[i] = CompletableFuture.completedFuture(statefulRedisConnections[i]);
        }
        synchronized (stateLock) {
            readers[slot] = toCache;
        }
        if (!orderSensitive) {
            StatefulRedisConnection<K, V> candidate = findRandomActiveConnection(selectedReaderCandidates, CompletableFuture::join);
            if (candidate != null) {
                return candidate;
            }
        }
        for (StatefulRedisConnection<K, V> candidate : statefulRedisConnections) {
            if (candidate.isOpen()) {
                return candidate;
            }
        }
        return statefulRedisConnections[0];
    });
}
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) StatefulRedisConnection(io.lettuce.core.api.StatefulRedisConnection) CompletableFuture(java.util.concurrent.CompletableFuture) RedisClusterNode(io.lettuce.core.cluster.models.partitions.RedisClusterNode) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ReadFrom(io.lettuce.core.ReadFrom)

Example 20 with RedisNodeDescription

use of io.lettuce.core.models.role.RedisNodeDescription in project lettuce-core by lettuce-io.

the class ClusterScanSupport method getNodeIds.

/**
 * Retrieve a list of node Ids to use for the SCAN operation.
 *
 * @param connection
 * @return
 */
private static List<String> getNodeIds(StatefulRedisClusterConnection<?, ?> connection) {
    List<String> nodeIds = new ArrayList<>();
    PartitionAccessor partitionAccessor = new PartitionAccessor(connection.getPartitions());
    for (RedisClusterNode redisClusterNode : partitionAccessor.getUpstream()) {
        if (connection.getReadFrom() != null) {
            List<RedisNodeDescription> readCandidates = (List) partitionAccessor.getReadCandidates(redisClusterNode);
            List<RedisNodeDescription> selection = connection.getReadFrom().select(new ReadFrom.Nodes() {

                @Override
                public List<RedisNodeDescription> getNodes() {
                    return readCandidates;
                }

                @Override
                public Iterator<RedisNodeDescription> iterator() {
                    return readCandidates.iterator();
                }
            });
            if (!selection.isEmpty()) {
                int indexToUse = 0;
                if (!OrderingReadFromAccessor.isOrderSensitive(connection.getReadFrom())) {
                    indexToUse = ThreadLocalRandom.current().nextInt(selection.size());
                }
                RedisClusterNode selectedNode = (RedisClusterNode) selection.get(indexToUse);
                nodeIds.add(selectedNode.getNodeId());
                continue;
            }
        }
        nodeIds.add(redisClusterNode.getNodeId());
    }
    return nodeIds;
}
Also used : ArrayList(java.util.ArrayList) RedisClusterNode(io.lettuce.core.cluster.models.partitions.RedisClusterNode) RedisNodeDescription(io.lettuce.core.models.role.RedisNodeDescription) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

RedisNodeDescription (io.lettuce.core.models.role.RedisNodeDescription)25 Test (org.junit.jupiter.api.Test)15 RedisClusterNode (io.lettuce.core.cluster.models.partitions.RedisClusterNode)9 ReadFrom (io.lettuce.core.ReadFrom)8 RedisURI (io.lettuce.core.RedisURI)7 StatefulRedisConnection (io.lettuce.core.api.StatefulRedisConnection)5 ArrayList (java.util.ArrayList)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 Iterator (java.util.Iterator)3 List (java.util.List)3 RedisConnectionException (io.lettuce.core.RedisConnectionException)2 ConnectionKey (io.lettuce.core.cluster.ClusterNodeConnectionFactory.ConnectionKey)2 ConnectionFuture (io.lettuce.core.ConnectionFuture)1 OrderingReadFromAccessor (io.lettuce.core.OrderingReadFromAccessor)1 RedisChannelWriter (io.lettuce.core.RedisChannelWriter)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