1 year ago
#387508
jimonthebarn
How to properly close Redis connection on intentional application shutdown?
We are using the list operations of the RedisTemplate (provided by spring-boot-starter-data-redis) to do a blocking call waiting for new items to arrive in a list within Redis. Since we are not listening to a single list but multiple ones we do this on a separate thread for each blocking list command call. That all works quite well until we shutdown the application (e.g. when running integration tests where the Redis is actually a testcontainer instance that is shut down after test execution) at which point we experience a myriad of stack traces resulting from the sudden shutdown of the Redis instance leading to the RedisCommandInterruptedException
s as well as the ConnectionWatchdog
trying to reconnect to the Redis instance which has already died:
15:19:10.352 [lettuce-eventExecutorLoop-1-4] INFO io.lettuce.core.protocol.ConnectionWatchdog - Reconnecting, last destination was localhost/127.0.0.1:56344
Caused by: io.lettuce.core.RedisCommandInterruptedException: Command interrupted
at io.lettuce.core.protocol.AsyncCommand.await(AsyncCommand.java:87)
at io.lettuce.core.internal.Futures.awaitOrCancel(Futures.java:244)
at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:74)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.await(LettuceConnection.java:1061)
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 172.17.0.1:56344
Is there a way to properly close the Redis connections and disable the ConnectionWatchDog for an intentional shutdown of the application?
Below is the simplified setup we currently have in place for the Redis wait:
@Component
@RequiredArgsConstructor
public class CustomMessageListener {
private final RedisTemplate<String, CustomMessage> template;
@Async("listeningExecutor")
public void listen(String list, AtomicBoolean keepListening) {
ListOperations<String, CustomMessage> listOperations = template.opsForList();
while (keepListening.get()) {
try {
var message = listOperations.rightPop(list, Duration.ofSeconds(10))
if (message != null) {
// do something with the message
}
} catch (Exception e) {
// log exception
}
}
}
}
spring-data-redis
0 Answers
Your Answer