Comments (5)
I would suggest using a ThreadPoolExecutor
or Lettuce's EventExecutorGroup
instead of starting a new thread on each connect. onRedisConnected
can be called for an existing connection as well (i.e. when reconnecting) so you should keep a mapping between RedisChannelHandler
and the runnable/ScheduledFuture
.
Is out of box token refreshing a feature request for spring.data.redis or for lettuce?
Not for Spring Data, but it could be one for Spring Cloud AWS.
Generally speaking, each cloud vendor does quirky things to Redis, trying to cover them all in the driver or in Spring Data would be an endless journey us trying to catch up with things that we neither have under control nor experience ourselves as we do not utilize Cloud Redis in our development or CI.
from spring-data-redis.
Lettuce's RedisCredentialsProvider
is the right place to obtain dynamically updated credentials. Spring Data provides a RedisCredentialsProviderFactory
that you can use to implement your own way how you would construct a RedisCredentialsProvider
. Lettuce calls RedisCredentialsProvider.resolveCredentials()
upon connect and reconnect.
That being said, you will have to implement a scheduled service that maintains current credentials for connects and reconnects.
An IAM authenticated connection to ElastiCache for Redis will automatically be disconnected after 12 hours
To keep connections alive, you could use RedisConnectionStateListener
that gets notified for each connection that is being created. With a timer, you could then send AUTH
commands. However, you need to be careful as AUTH
commands that would interleave with transactions may interfere with command results. If you don't use transactions, then you don't need to worry.
Keeping track of active connections can be cumbersome. The alternative would be waiting for a disconnect.
from spring-data-redis.
Thanks for the response, I have implemented the credential provider stuff adapted form aws samples. AWS docs say MULTI EXEC transactions aren't supported with IAM authentication so I have avoided those in our other service and use Lua scripts instead.
For this specific service we are subscribing to a redis topic only and need the connection to stay alive otherwise we will have to do some expensive work each time it disconnects.
I'm looking into how to use RedisConnectionStateListener now . The beans I currently have access to are: RedisMessageListenerContainer, LettuceConnectionFactory, MessageListenerAdapter, MeterRegistry
from spring-data-redis.
Experimenting with a main and using your RedisConnectionStateListener suggestion, I came up with the below. Any gotchas I should be aware of?
Is out of box token refreshing a feature request for spring.data.redis or for lettuce? I'am providing the credential provider when setting up the ConnectionFactory so it has everything it needs to so. Maybe users could provide an AUTH refresh parameter...
public static void main(String[] args) {
AwsV2ClientsConfig awsV2ClientsConfig = new AwsV2ClientsConfig(Region.US_EAST_1);
RedisProperties redisProperties = new RedisProperties();
redisProperties.set...
// Set redis host data, user, etc
...
RedisConfiguration redisConfiguration = new RedisConfiguration(redisProperties);
LettuceConnectionFactory lettuceConnectionFactory = redisConfiguration.redisConnectionFactory(
redisProperties, awsV2ClientsConfig);
var credProvider = redisConfiguration.getRedisIAMAuthCredentialsProvider(redisProperties,
awsV2ClientsConfig);
RedisConnectionStateListener redisConnectionStateListener = new RedisConnectionStateListener() {
@Override
public void onRedisConnected(RedisChannelHandler<?, ?> connection) {
RedisConnectionStateListener.super.onRedisConnected(connection);
new Thread(() -> {
var lastUpdate = 0L;
// Loop starts when connection is first opened.
while (true) {
if (connection.isOpen()) {
// First iteration
if (lastUpdate == 0L) {
System.out.println("NEW CONNECTION");
lastUpdate = Instant.now().getEpochSecond();
} else {
/*
* Subsequent iterations while the connection is still open
* todo: add check for time gap, only want to do this close to the 12hr mark
*/
System.out.println("REFRESH CONNECTION");
var con = (StatefulRedisConnection) connection;
// Get a new token from the credential provider.
var resp = con.sync().auth(redisProperties.getRedisUser(),
new String(credProvider.resolveCredentials().block().getPassword()));
lastUpdate = Instant.now().getEpochSecond();
System.out.println(resp); // OK
}
try {
// todo revise this sleep
Thread.sleep(10000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
// Exit this thread when the connection is no longer active.
if (lastUpdate > 0L) {
return;
}
}
}
}, "Thread-RedisConnectionRefresher").start();
}
};
lettuceConnectionFactory.start();
lettuceConnectionFactory.getNativeClient().addListener(redisConnectionStateListener);
var connection = lettuceConnectionFactory.getConnection();
System.out.println(connection.publish("pubsub:sometopic".getBytes(), "test".getBytes()));
while (true) {
}
}
from spring-data-redis.
Thanks, I ended up using a concurrent hash map which is populated and cleared by onRedisConnected and onRedisDisconnected then a spring @scheduled method to periodically send the AUTH command.
from spring-data-redis.
Related Issues (20)
- Upgrade to Maven Wrapper 3.9.8
- Upgrade to Maven Wrapper 3.9.8
- Upgrade to Lettuce 6.4
- Upgrade to Jedis 5.1.4
- Refactor Tests to `instanceof` pattern variable HOT 2
- Release 3.2.10 (2023.1.10)
- Release 3.3.4 (2024.0.4)
- why opsForHash() method always returns a new instance object
- Add Support to Jedis readOnlyForReplicas property HOT 2
- Add `@Serial` annotation to all `serialVersionUID` fields
- Why bitField offset argument is converted to `int`?
- ReactiveListOperations left/right pop operations fail with Duration with fractions of second HOT 2
- Upgrade to Jedis 5.1.5
- Do not sync cache when @CachePut HOT 3
- When json is deserialized, the JsonDeserializer returned in the custom ContextualDeserializer is not executed. HOT 2
- Jackson2HashMapper fails to deserialize enum property when flatten=true HOT 1
- Support deserialization in `GenericJackson2JsonRedisSerializer` when using custom `JsonFactory` HOT 1
- Negative maxlen for XAddOptions is ignored HOT 3
- Exception thrown on application shutdown when using redis with RedisIndexedWebSession enabled HOT 1
- Use before assignment of asyncDedicatedConnection in LettuceConnection HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-data-redis.