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

io.lettuce.core.cluster.ClusterPubSubConnectionProvider Maven / Gradle / Ivy

Go to download

Advanced and thread-safe Java Redis client for synchronous, asynchronous, and reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs and much more.

The newest version!
package io.lettuce.core.cluster;

import io.lettuce.core.ConnectionFuture;
import io.lettuce.core.RedisChannelWriter;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.cluster.models.partitions.Partitions;
import io.lettuce.core.cluster.models.partitions.RedisClusterNode;
import io.lettuce.core.cluster.pubsub.RedisClusterPubSubListener;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.pubsub.RedisPubSubAdapter;
import io.lettuce.core.pubsub.RedisPubSubListener;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import io.lettuce.core.resource.ClientResources;

/**
 * {@link ClusterConnectionProvider} to provide {@link StatefulRedisPubSubConnection}s for Redis Cluster use.
 * 

* {@link StatefulRedisPubSubConnection}s provided by this {@link ClusterConnectionProvider} get a {@link RedisPubSubListener} * registered that propagates received events to an upstream {@link RedisClusterPubSubListener} to provide message propagation. * Message propagation performs a {@link RedisClusterNode} lookup to distinguish notifications between cluster nodes. * * @author Mark Paluch * @since 4.4 */ class ClusterPubSubConnectionProvider extends PooledClusterConnectionProvider { private final RedisClusterClient redisClusterClient; private final RedisCodec redisCodec; private final RedisClusterPubSubListener notifications; /** * Creates a new {@link ClusterPubSubConnectionProvider}. * * @param redisClusterClient must not be {@code null}. * @param clusterWriter must not be {@code null}. * @param redisCodec must not be {@code null}. * @param notificationTarget must not be {@code null}. * @param clusterEventListener must not be {@code null}. */ ClusterPubSubConnectionProvider(RedisClusterClient redisClusterClient, RedisChannelWriter clusterWriter, RedisCodec redisCodec, RedisClusterPubSubListener notificationTarget, ClusterEventListener clusterEventListener) { super(redisClusterClient, clusterWriter, redisCodec, clusterEventListener); this.redisClusterClient = redisClusterClient; this.redisCodec = redisCodec; this.notifications = notificationTarget; } @Override protected ClusterNodeConnectionFactory getConnectionFactory(RedisClusterClient redisClusterClient) { return new DecoratingClusterNodeConnectionFactory(new PubSubNodeConnectionFactory(redisClusterClient.getResources())); } @SuppressWarnings("unchecked") class PubSubNodeConnectionFactory extends AbstractClusterNodeConnectionFactory { PubSubNodeConnectionFactory(ClientResources clientResources) { super(clientResources); } @Override public ConnectionFuture> apply(ConnectionKey key) { if (key.nodeId != null) { // NodeId connections do not provide command recovery due to cluster reconfiguration return redisClusterClient.connectPubSubToNodeAsync((RedisCodec) redisCodec, key.nodeId, getSocketAddressSupplier(key)); } // Host and port connections do provide command recovery due to cluster reconfiguration return redisClusterClient.connectPubSubToNodeAsync((RedisCodec) redisCodec, key.host + ":" + key.port, getSocketAddressSupplier(key)); } } @SuppressWarnings("unchecked") class DecoratingClusterNodeConnectionFactory implements ClusterNodeConnectionFactory { private final ClusterNodeConnectionFactory delegate; DecoratingClusterNodeConnectionFactory(ClusterNodeConnectionFactory delegate) { this.delegate = delegate; } @Override public void setPartitions(Partitions partitions) { delegate.setPartitions(partitions); } @Override public ConnectionFuture> apply(ConnectionKey key) { ConnectionFuture> future = delegate.apply(key); if (key.nodeId != null) { return future.thenApply(connection -> { ((StatefulRedisPubSubConnection) connection) .addListener(new DelegatingRedisClusterPubSubListener(key.nodeId)); return connection; }); } return future.thenApply(connection -> { ((StatefulRedisPubSubConnection) connection) .addListener(new DelegatingRedisClusterPubSubListener(key.host, key.port)); return connection; }); } } class DelegatingRedisClusterPubSubListener extends RedisPubSubAdapter { private final String nodeId; private final String host; private final int port; DelegatingRedisClusterPubSubListener(String nodeId) { this.nodeId = nodeId; this.host = null; this.port = 0; } DelegatingRedisClusterPubSubListener(String host, int port) { this.nodeId = null; this.host = host; this.port = port; } @Override public void message(K channel, V message) { notifications.message(getNode(), channel, message); } @Override public void message(K pattern, K channel, V message) { notifications.message(getNode(), pattern, channel, message); } @Override public void subscribed(K channel, long count) { notifications.subscribed(getNode(), channel, count); } @Override public void psubscribed(K pattern, long count) { notifications.psubscribed(getNode(), pattern, count); } @Override public void unsubscribed(K channel, long count) { notifications.unsubscribed(getNode(), channel, count); } @Override public void punsubscribed(K pattern, long count) { notifications.punsubscribed(getNode(), pattern, count); } @Override public void smessage(K shardChannel, V message) { notifications.smessage(getNode(), shardChannel, message); } @Override public void ssubscribed(K channel, long count) { notifications.ssubscribed(getNode(), channel, count); } @Override public void sunsubscribed(K channel, long count) { notifications.sunsubscribed(getNode(), channel, count); } private RedisClusterNode getNode() { return nodeId != null ? getPartitions().getPartitionByNodeId(nodeId) : getPartitions().getPartition(host, port); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy