Skip to content
This repository has been archived by the owner on Jan 9, 2024. It is now read-only.

Support reading from replicas on pipeline executions #450

Merged
merged 1 commit into from
Apr 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions rediscluster/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,50 @@
TimeoutError,
)

# Not complete, but covers the major ones
# https://redis.io/commands
READ_COMMANDS = frozenset([
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since I had to move READ_COMMANDS to make it available to the pipeline object I ended up converting it into a frozenset (stolen from #406) since it does speed up lookups by an order of magnitude 😮

"BITCOUNT",
"BITPOS",
"EXISTS",
"GEODIST",
"GEOHASH",
"GEOPOS",
"GEORADIUS",
"GEORADIUSBYMEMBER",
"GET",
"GETBIT",
"GETRANGE",
"HEXISTS",
"HGET",
"HGETALL",
"HKEYS",
"HLEN",
"HMGET",
"HSTRLEN",
"HVALS",
"KEYS",
"LINDEX",
"LLEN",
"LRANGE",
"MGET",
"PTTL",
"RANDOMKEY",
"SCARD",
"SDIFF",
"SINTER",
"SISMEMBER",
"SMEMBERS",
"SRANDMEMBER",
"STRLEN",
"SUNION",
"TTL",
"ZCARD",
"ZCOUNT",
"ZRANGE",
"ZSCORE",
])


log = logging.getLogger(__name__)

Expand Down Expand Up @@ -168,50 +212,6 @@ class RedisCluster(Redis):
], 'slot-id'),
)

# Not complete, but covers the major ones
# https://redis.io/commands
READ_COMMANDS = [
"BITCOUNT",
"BITPOS",
"EXISTS",
"GEODIST",
"GEOHASH",
"GEOPOS",
"GEORADIUS",
"GEORADIUSBYMEMBER",
"GET",
"GETBIT",
"GETRANGE",
"HEXISTS",
"HGET",
"HGETALL",
"HKEYS",
"HLEN",
"HMGET",
"HSTRLEN",
"HVALS",
"KEYS",
"LINDEX",
"LLEN",
"LRANGE",
"MGET",
"PTTL",
"RANDOMKEY",
"SCARD",
"SDIFF",
"SINTER",
"SISMEMBER",
"SMEMBERS",
"SRANDMEMBER",
"STRLEN",
"SUNION",
"TTL",
"ZCARD",
"ZCOUNT",
"ZRANGE",
"ZSCORE",
]

RESULT_CALLBACKS = dict_merge(
string_keys_to_dict([
"BGREWRITEAOF",
Expand Down Expand Up @@ -608,7 +608,7 @@ def _execute_command(self, *args, **kwargs):
else:
node = self.connection_pool.get_node_by_slot(
slot,
self.read_from_replicas and (command in self.READ_COMMANDS)
self.read_from_replicas and (command in READ_COMMANDS)
)
is_read_replica = node['server_type'] == 'slave'

Expand Down
4 changes: 2 additions & 2 deletions rediscluster/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys

# rediscluster imports
from .client import RedisCluster
from .client import RedisCluster, READ_COMMANDS
from .exceptions import (
RedisClusterException, AskError, MovedError, TryAgainError, ClusterDownError,
)
Expand Down Expand Up @@ -194,7 +194,7 @@ def _send_cluster_commands(self, stack, raise_on_error=True, allow_redirections=
# refer to our internal node -> slot table that tells us where a given
# command should route to.
slot = self._determine_slot(*c.args)
node = self.connection_pool.get_node_by_slot(slot)
node = self.connection_pool.get_node_by_slot(slot, self.read_from_replicas and c.args[0] in READ_COMMANDS)

# little hack to make sure the node name is populated. probably could clean this up.
self.connection_pool.nodes.set_node_name(node)
Expand Down