Skip to content

LettuceConnectionFactory lifecycle stops connections before depending components are stopped #2957

Closed
@kains4

Description

@kains4
2024-08-06 08:28:33.929 �[31mWARN �[0;39m [SpringApplicationShutdownHook] �[36mo.s.d.r.c.l.LettucePoolingConnectionProvider�[0;39m - LettucePoolingConnectionProvider contains unreleased connections
2024-08-06 08:28:34.054 �[31mWARN �[0;39m [SpringApplicationShutdownHook] �[36mo.s.d.r.l.RedisMessageListenerContainer�[0;39m - Unable to unsubscribe from subscriptions
org.springframework.data.redis.connection.PoolException: Returned connection io.lettuce.core.pubsub.StatefulRedisPubSubConnectionImpl@46831b04 was either previously returned or does not belong to this connection provider
	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.release(LettucePoolingConnectionProvider.java:153)
	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.release(LettuceConnectionFactory.java:1787)
	at org.springframework.data.redis.connection.lettuce.LettuceSubscription.doClose(LettuceSubscription.java:102)
	at org.springframework.data.redis.connection.util.AbstractSubscription.close(AbstractSubscription.java:105)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.closeSubscription(RedisMessageListenerContainer.java:1301)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doUnsubscribe(RedisMessageListenerContainer.java:1264)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.lambda$unsubscribeAll$2(RedisMessageListenerContainer.java:1257)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.lambda$doInLock$9(RedisMessageListenerContainer.java:1384)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doInLock(RedisMessageListenerContainer.java:1392)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doInLock(RedisMessageListenerContainer.java:1384)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.unsubscribeAll(RedisMessageListenerContainer.java:1252)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer.doUnsubscribe(RedisMessageListenerContainer.java:511)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer.stopListening(RedisMessageListenerContainer.java:493)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer.removeListener(RedisMessageListenerContainer.java:764)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer.removeMessageListener(RedisMessageListenerContainer.java:587)
	at org.springframework.data.redis.listener.RedisMessageListenerContainer.removeMessageListener(RedisMessageListenerContainer.java:614)

I'm using a RedisTemplate with spring boot version 3.3.0 and spring-data-redis 3.3.0.
When I stop our spring service or excute test task, I got the message as above.
I think this issue has relation with 2330 issue( #2330).
I didn't this message when I use spring boot 3.1.0. So I have tested varios spring boot version above 3.1.0.
And then I detected this issue was happed above spring boot version 3.2.0.

Activity

mp911de

mp911de commented on Aug 6, 2024

@mp911de
Member

StatefulRedisPubSubConnectionImpl indicates that you're not using Redis Cluster here.

In any case, RedisMessageListenerContainer is being closed after LettuceConnectionFactory. Spring Data doesn't manage the lifecycle of RedisMessageListenerContainer. Either your application or an additional component does so.

Please provide a minimal yet complete sample that reproduces the problem.
You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

kains4

kains4 commented on Aug 6, 2024

@kains4
Author

RedisTest.zip
Here is a test code you requested.
image
Just run service and stop and then you can see a result as above.

changed the title [-]LettuceConnectionFactory.destroy(…) releases cluster connections after shutting down the connection pool[/-] [+]`LettuceConnectionFactory` lifecycle stops connections before depending components are stopped[/+] on Aug 7, 2024
mp911de

mp911de commented on Aug 7, 2024

@mp911de
Member

Thanks for the details. With LettuceConnectionFactory and JedisConnectionFactory being lifecyle beans, the stop() operation stops connection operations while RedisKeyValueAdapter remains just DisposableBean stopping its components at a later time.

We might explore making RedisKeyValueAdapter also a lifecycle bean that can stop its message listener usage at an earlier time.

added a commit that references this issue on Aug 11, 2024
20688c5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Participants

      @mp911de@christophstrobl@kains4@spring-projects-issues

      Issue actions

        `LettuceConnectionFactory` lifecycle stops connections before depending components are stopped · Issue #2957 · spring-projects/spring-data-redis