Skip to content

Commit d0d0b62

Browse files
committed
Refactored retries, fixed comments, fixed linters
1 parent 2343beb commit d0d0b62

File tree

4 files changed

+21
-21
lines changed

4 files changed

+21
-21
lines changed

docs/advanced_features.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ the server.
180180
Please note:
181181

182182
- RedisCluster pipelines currently only support key-based commands.
183-
- The pipeline gets its ‘read_from_replicas’ value from the
183+
- The pipeline gets its ‘load_balancing_strategy’ value from the
184184
cluster’s parameter. Thus, if read from replications is enabled in
185185
the cluster instance, the pipeline will also direct read commands to
186186
replicas.
@@ -204,7 +204,7 @@ is exactly that: a compromise. While this behavior is different from
204204
non-transactional cluster pipelines, it simplifies migration of clients
205205
from standalone to cluster under some circumstances. Note that application
206206
code that issues multi/exec commands on a standalone client without
207-
embedding them within a pipeline would eventually get ‘AttributeError’s.
207+
embedding them within a pipeline would eventually get ‘AttributeError’.
208208
With this approach, if the application uses ‘client.pipeline(transaction=True)’,
209209
then switching the client with a cluster-aware instance would simplify
210210
code changes (to some extent). This may be true for application code that

redis/cluster.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,8 +1237,6 @@ def _execute_command(self, target_node, *args, **kwargs):
12371237
except AuthenticationError:
12381238
raise
12391239
except (ConnectionError, TimeoutError) as e:
1240-
# Connection retries are being handled in the node's
1241-
# Retry object.
12421240
# ConnectionError can also be raised if we couldn't get a
12431241
# connection from the pool before timing out, so check that
12441242
# this is an actual connection before attempting to disconnect.
@@ -1854,7 +1852,7 @@ def remap_host_port(self, host: str, port: int) -> Tuple[str, int]:
18541852

18551853
def find_connection_owner(self, connection: Connection) -> Optional[Redis]:
18561854
node_name = get_node_name(connection.host, connection.port)
1857-
for node in self.nodes_cache.values():
1855+
for node in tuple(self.nodes_cache.values()):
18581856
if node.redis_connection:
18591857
conn_args = node.redis_connection.connection_pool.connection_kwargs
18601858
if node_name == get_node_name(
@@ -2550,7 +2548,7 @@ def multi(self):
25502548
"""
25512549
Starts transactional context.
25522550
2553-
See: ClusterPipeline.reset()
2551+
See: ClusterPipeline.multi()
25542552
"""
25552553
pass
25562554

@@ -2706,9 +2704,9 @@ def send_cluster_commands(
27062704
self, stack, raise_on_error=True, allow_redirections=True
27072705
):
27082706
"""
2709-
Wrapper for CLUSTERDOWN error handling.
2707+
Wrapper for RedisCluster.ERRORS_ALLOW_RETRY errors handling.
27102708
2711-
If the cluster reports it is down it is assumed that:
2709+
If one of the retryable exceptions has been thrown we assume that:
27122710
- connection_pool was disconnected
27132711
- connection_pool was reseted
27142712
- refereh_table_asap set to True
@@ -2816,11 +2814,10 @@ def _send_cluster_commands(
28162814
# we write to all the open sockets for each node first,
28172815
# before reading anything
28182816
# this allows us to flush all the requests out across the
2819-
# network essentially in parallel
2820-
# so that we can read them all in parallel as they come back.
2817+
# network
2818+
# so that we can read them from different sockets as they come back.
28212819
# we dont' multiplex on the sockets as they come available,
28222820
# but that shouldn't make too much difference.
2823-
node_commands = nodes.values()
28242821
try:
28252822
node_commands = nodes.values()
28262823
for n in node_commands:
@@ -3024,7 +3021,7 @@ class TransactionStrategy(AbstractStrategy):
30243021
IMMEDIATE_EXECUTE_COMMANDS = {"WATCH", "UNWATCH"}
30253022
UNWATCH_COMMANDS = {"DISCARD", "EXEC", "UNWATCH"}
30263023
SLOT_REDIRECT_ERRORS = (AskError, MovedError)
3027-
CONNECTION_ERRORS = (ConnectionError,OSError,ClusterDownError)
3024+
CONNECTION_ERRORS = (ConnectionError, OSError, ClusterDownError)
30283025

30293026
def __init__(self, pipe: ClusterPipeline):
30303027
super().__init__(pipe)
@@ -3033,6 +3030,10 @@ def __init__(self, pipe: ClusterPipeline):
30333030
self._pipeline_slots: Set[int] = set()
30343031
self._transaction_connection: Optional[Connection] = None
30353032
self._executing = False
3033+
self._retry = copy(self._pipe.retry)
3034+
self._retry.update_supported_errors(
3035+
RedisCluster.ERRORS_ALLOW_RETRY + self.SLOT_REDIRECT_ERRORS
3036+
)
30363037

30373038
def _get_client_and_connection_for_transaction(self) -> Tuple[Redis, Connection]:
30383039
"""
@@ -3105,9 +3106,7 @@ def _validate_watch(self):
31053106
self._watching = True
31063107

31073108
def _immediate_execute_command(self, *args, **options):
3108-
retry = copy(self._pipe.retry)
3109-
retry.update_supported_errors([AskError, MovedError])
3110-
return retry.call_with_retry(
3109+
return self._retry.call_with_retry(
31113110
lambda: self._get_connection_and_send_command(*args, **options),
31123111
self._reinitialize_on_error,
31133112
)
@@ -3137,7 +3136,10 @@ def _reinitialize_on_error(self, error):
31373136
if type(error) in self.SLOT_REDIRECT_ERRORS and self._executing:
31383137
raise WatchError("Slot rebalancing occurred while watching keys")
31393138

3140-
if type(error) in self.SLOT_REDIRECT_ERRORS or type(error) in self.CONNECTION_ERRORS:
3139+
if (
3140+
type(error) in self.SLOT_REDIRECT_ERRORS
3141+
or type(error) in self.CONNECTION_ERRORS
3142+
):
31413143
if self._transaction_connection:
31423144
self._transaction_connection = None
31433145

@@ -3169,9 +3171,7 @@ def execute(self, raise_on_error: bool = True) -> List[Any]:
31693171
def _execute_transaction_with_retries(
31703172
self, stack: List["PipelineCommand"], raise_on_error: bool
31713173
):
3172-
retry = copy(self._pipe.retry)
3173-
retry.update_supported_errors([AskError, MovedError])
3174-
return retry.call_with_retry(
3174+
return self._retry.call_with_retry(
31753175
lambda: self._execute_transaction(stack, raise_on_error),
31763176
self._reinitialize_on_error,
31773177
)

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from tests.ssl_utils import get_tls_certificates
3131

3232
REDIS_INFO = {}
33-
default_redis_url = "redis://localhost:6379/0"
33+
default_redis_url = "redis://localhost:16379/0"
3434
default_protocol = "2"
3535
default_redismod_url = "redis://localhost:6479"
3636

tests/test_cluster_transaction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from redis.cluster import PRIMARY, ClusterNode, NodesManager, RedisCluster
1212
from redis.retry import Retry
1313

14-
from .conftest import skip_if_server_version_lt, wait_for_command
14+
from .conftest import skip_if_server_version_lt
1515

1616

1717
def _find_source_and_target_node_for_slot(

0 commit comments

Comments
 (0)