Make sure free_client() method is called on connection retries. #57
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.
We need to explicitly call free_client() within the retry loop, as the ensure section is called only once, on rescue block exit.
Every time a redis command is sent, client_for() is called, adding the client connection object to a stack. Under normal usage, a subsequent free_client() call is made, removing this client object from the stack. However, on connection failure, with retries enabled (the default), the rescue::retry loop triggers client_for() multiple times, without matching free_client() calls (ruby ensure sections are only called at final rescue block exit). This results in duplicate copies of the client object to remain in stack, which effectively caches the client connection forever, resulting in perpetual stale server selection, breaking failover completely.
We ran into this almost immediately when testing failure handling with a simple rpush+blpop ping/pong test.
I'm pretty sure #42 is a manifestation of the same problem, and why using .clear instead of .pop happened to "fix" things for them.