Avoid cast to StatefulRedisConnection upon eager LettuceConnectionFactory initialization.

We now no longer try to cast the Lettuce connection to StatefulRedisConnection when eagerly initializing the shared connection. Instead, we now introduced another method to obtain the cluster connection.

Closes #2186
This commit is contained in:
Mark Paluch
2021-11-12 08:51:41 +01:00
parent 2d08f28b8a
commit bac59c0e2f
2 changed files with 68 additions and 11 deletions

View File

@@ -438,9 +438,7 @@ public class LettuceConnectionFactory
RedisClusterClient clusterClient = (RedisClusterClient) client;
StatefulRedisClusterConnection<byte[], byte[]> sharedConnection = getShareNativeConnection()
? (StatefulRedisClusterConnection<byte[], byte[]>) getOrCreateSharedConnection().getConnection()
: null;
StatefulRedisClusterConnection<byte[], byte[]> sharedConnection = getSharedClusterConnection();
LettuceClusterTopologyProvider topologyProvider = new LettuceClusterTopologyProvider(clusterClient);
return doCreateLettuceClusterConnection(sharedConnection, connectionProvider, topologyProvider,
@@ -540,7 +538,12 @@ public class LettuceConnectionFactory
resetConnection();
getSharedConnection();
if (isClusterAware()) {
getSharedClusterConnection();
} else {
getSharedConnection();
}
getSharedReactiveConnection();
}
@@ -1081,12 +1084,27 @@ public class LettuceConnectionFactory
}
/**
* @return the shared connection using {@literal byte} array encoding for imperative API use. {@literal null} if
* {@link #getShareNativeConnection() connection sharing} is disabled.
* @return the shared connection using {@literal byte[]} encoding for imperative API use. {@literal null} if
* {@link #getShareNativeConnection() connection sharing} is disabled or when connected to Redis Cluster.
*/
@Nullable
protected StatefulRedisConnection<byte[], byte[]> getSharedConnection() {
return shareNativeConnection ? (StatefulRedisConnection) getOrCreateSharedConnection().getConnection() : null;
return shareNativeConnection && !isClusterAware()
? (StatefulRedisConnection) getOrCreateSharedConnection().getConnection()
: null;
}
/**
* @return the shared cluster connection using {@literal byte[]} encoding for imperative API use. {@literal null} if
* {@link #getShareNativeConnection() connection sharing} is disabled or when connected to Redis
* Standalone/Sentinel/Master-Replica.
* @since 2.5.7
*/
@Nullable
protected StatefulRedisClusterConnection<byte[], byte[]> getSharedClusterConnection() {
return shareNativeConnection && isClusterAware()
? (StatefulRedisClusterConnection) getOrCreateSharedConnection().getConnection()
: null;
}
/**

View File

@@ -48,6 +48,7 @@ import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.connection.lettuce.extension.LettuceConnectionFactoryExtension;
import org.springframework.data.redis.test.condition.EnabledOnRedisClusterAvailable;
import org.springframework.data.redis.test.extension.LettuceTestClientResources;
/**
@@ -85,7 +86,6 @@ class LettuceConnectionFactoryTests {
factory.destroy();
}
@SuppressWarnings("rawtypes")
@Test
void testGetNewConnectionOnError() throws Exception {
@@ -462,9 +462,8 @@ class LettuceConnectionFactoryTests {
RedisConnection connection = factory.getConnection();
assertThatThrownBy(() -> connection.pSubscribe((message, pattern) -> {
}, "foo".getBytes())).isInstanceOf(RedisConnectionFailureException.class)
.hasCauseInstanceOf(UnsupportedOperationException.class);
assertThatThrownBy(() -> connection.pSubscribe((message, pattern) -> {}, "foo".getBytes()))
.isInstanceOf(RedisConnectionFailureException.class).hasCauseInstanceOf(UnsupportedOperationException.class);
connection.close();
factory.destroy();
@@ -558,4 +557,44 @@ class LettuceConnectionFactoryTests {
connection.close();
}
@Test // GH-2186
void shouldInitializeMasterReplicaConnectionsEagerly() {
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder()
.clientResources(LettuceTestClientResources.getSharedClientResources()).build();
RedisStaticMasterReplicaConfiguration elastiCache = new RedisStaticMasterReplicaConfiguration(
SettingsUtils.getHost()).node(SettingsUtils.getHost(), SettingsUtils.getPort() + 1);
LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache, configuration);
factory.setEagerInitialization(true);
factory.afterPropertiesSet();
assertThat(factory.getSharedConnection()).isNotNull();
assertThat(factory.getSharedClusterConnection()).isNull();
factory.getConnection().close();
factory.destroy();
}
@Test // GH-2186
@EnabledOnRedisClusterAvailable
void shouldInitializeClusterConnectionsEagerly() {
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder()
.clientResources(LettuceTestClientResources.getSharedClientResources()).build();
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.clusterConfiguration(),
configuration);
factory.setEagerInitialization(true);
factory.afterPropertiesSet();
assertThat(factory.getSharedConnection()).isNull();
assertThat(factory.getSharedClusterConnection()).isNotNull();
factory.getConnection().close();
factory.destroy();
}
}