-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Hitless upgrade support implementation for synchronous Redis client. #3713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
0304da5
to
ee27bd2
Compare
… tests for maintenance_events.py file
…tion pool - this should be a separate PR
… Refactored the maintenance events tests not to be multithreaded - we don't need it for those tests.
…ot processed in in Moving state. Tests are updated
…ply them during connect
ee27bd2
to
0f9734c
Compare
0f9734c
to
6d496f0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request implements hitless upgrade support for the synchronous Redis client by introducing maintenance event handling capabilities. This feature allows Redis clients to gracefully handle cluster maintenance operations like node migrations and replacements without dropping connections or failing commands.
Key changes include:
- Added comprehensive maintenance events framework with event classes and handlers
- Extended connection pool to support maintenance states and temporary configurations
- Integrated push notification handlers for RESP3 protocol maintenance events
Reviewed Changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 9 comments.
Show a summary per file
File | Description |
---|---|
tests/test_maintenance_events_handling.py | Comprehensive integration tests for maintenance events handling with mock sockets |
tests/test_maintenance_events.py | Unit tests for maintenance event classes, configurations, and handlers |
tests/test_connection_pool.py | Added should_reconnect method to test connection mock |
redis/maintenance_events.py | Core maintenance events framework with event classes, configurations, and handlers |
redis/connection.py | Enhanced connection and pool classes with maintenance event support and state management |
redis/client.py | Integrated maintenance events configuration into Redis client initialization |
redis/asyncio/connection.py | Added maintenance mode support for async blocking connection pool |
redis/_parsers/resp3.py | Enhanced RESP3 parser with push notification handlers for maintenance events |
redis/_parsers/hiredis.py | Added maintenance event push handlers to hiredis parser |
redis/_parsers/base.py | Added maintenance event parsing logic and handler registration methods |
|
||
def set_tmp_settings( | ||
self, | ||
tmp_host_address: Optional[Union[str, object]] = SENTINEL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using SENTINEL as a default value but SENTINEL is not defined in this scope. This could cause a NameError.
Copilot uses AI. Check for mistakes.
redis/connection.py
Outdated
@@ -1646,6 +1815,154 @@ def re_auth_callback(self, token: TokenInterface): | |||
for conn in self._in_use_connections: | |||
conn.set_re_auth_token(token) | |||
|
|||
def update_connection_kwargs_with_tmp_settings( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make it more generic? Something like update_connection_kwargs(**kwargs)
redis/connection.py
Outdated
self.connection_kwargs.update({"tmp_host_address": tmp_host_address}) | ||
self.connection_kwargs.update({"tmp_relax_timeout": tmp_relax_timeout}) | ||
|
||
def update_connections_tmp_settings( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same here, could it be more generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I see why I didn't understand the next comment :) This is an old function that has been removed and split into two separate functions.
I'll see how will be appropriate to combine some of the into more generic ones or which of the newly added ones can be transformed into more generic ones(like the one mentioned above --> update_connection_kwargs)
conn, tmp_host_address, tmp_relax_timeout | ||
) | ||
|
||
def update_connections_current_timeout( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be not needed if update_connections_tmp_settings
will be more generic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vladvildanov I didn’t quite understand this one — do you mean having a single generic method that handles all possible updates to object properties, including the socket timeout update for already connected connections?
I intentionally separated them to make it easier to follow what exactly gets updated during notification handling — specifically, whether we’re only updating properties used during connect
, or actually changing the behavior of already established socket connections.
redis/connection.py
Outdated
connections_in_queue = {conn for conn in self.pool.queue if conn} | ||
for conn in self._connections: | ||
if conn not in connections_in_queue: | ||
if address_type_to_match == "connected": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of duplicate of this part:
if address_type_to_match == "connected":
if matching_address and conn.getpeername() != matching_address:
continue
Maybe it makes to create a method that filter connections by this criteria and returns filtered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to iterate over the different lists once and not create additional lists holding references to the connection objects that match the filter, so I think it will be better to create a new helper method that just checks if the connection should be updated or not. You are right - it is a lot of code duplication :)
Pull Request check-list
Please make sure to review and check all of these items:
NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.
Description of change
Hitless upgrade support implementation for synchronous Redis client.