Fix redundant disposal in LettucePoolingConnectionProvider by implementing SmartLifecycle #3100 #3164
+69
−35
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Enhancements to
LettuceConnectionFactory
:ClusterCommandExecutor
during thestop
method to ensure resources are released cleanly.ClusterCommandExecutor
from thedestroy
method, as it is now handled in thestop
method.dispose
method to encapsulate the cleanup logic forClusterCommandExecutor
, improving code readability and maintainability.Enhancements to
LettucePoolingConnectionProvider
:SmartLifecycle
to manage the lifecycle of the connection provider, includingstart
,stop
, andisRunning
methods.AtomicReference
-basedState
enum to track the lifecycle state of the connection provider, ensuring thread-safe transitions between states.These updates improve the robustness and maintainability of the connection handling logic in the Spring Data Redis project.
I have found out that #3100 was reproduced when redis run with cluster mode.
LettuceConnectionFactory uses a connectionProvider that refered at ClusterCommandExecuter. When redis run with Cluster mode, it uses LettucePoolingConnectionProvider, which only implements DisposableBean.
When the LettuceConnectionFactory disposed, it disposes ConnectionProvider first, and disposes ClusterCommandExecuter next.
And when the ClusterCommandExecuter disposed, it disposes the connectionProvider - shared with LettuceConnectionFactory. As a result, LettucePoolingConnectionProvider's destroy method called twice.
Finally, the LettucePoolingConnectionProvider tried releasing connections in it's pool - that has 0 connections.
To solve this issue, I've implemented SmartLifeCycle at LettucePoolingConnectionProvider, and prevent duplicated stop method execution by AtomicReference based state management.
Solved #3100, See #3103