Skip to content

Commit 55df051

Browse files
committed
Adding maintenance notification configuration to cluster client. Integration with testing helper proxy server. (#3844)
* Adding maint_notifications_config to RedisCluster's NodesManager * Adding Redis Proxy integration * Migrating test proxy helper to use custom https client
1 parent 0894218 commit 55df051

File tree

8 files changed

+666
-11
lines changed

8 files changed

+666
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ docker/stunnel/keys
2727
/dockers/replica/
2828
/dockers/sentinel/
2929
/dockers/redis-stack/
30+
/experimenting/

docker-compose.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ x-client-libs-stack-image: &client-libs-stack-image
66
x-client-libs-image: &client-libs-image
77
image: "redislabs/client-libs-test:${CLIENT_LIBS_TEST_IMAGE_TAG:-8.4.0}"
88

9+
networks:
10+
redis-net:
11+
driver: bridge
912
services:
1013

1114
redis:
@@ -106,3 +109,42 @@ services:
106109
- standalone
107110
- all-stack
108111
- all
112+
113+
redis-proxied:
114+
<<: *client-libs-image
115+
container_name: redis-proxied
116+
ports:
117+
- "3000:3000"
118+
networks:
119+
- redis-net
120+
healthcheck:
121+
test: ["CMD", "redis-cli", "-p", "3000", "PING"]
122+
interval: 10s
123+
timeout: 3s
124+
retries: 5
125+
126+
resp-proxy:
127+
image: redislabs/client-resp-proxy
128+
container_name: resp-proxy
129+
environment:
130+
LISTEN_HOST: "0.0.0.0"
131+
LISTEN_PORT: "15379,15380,15381"
132+
TARGET_HOST: "redis-proxied"
133+
TARGET_PORT: "3000"
134+
API_PORT: "4000"
135+
ENABLE_LOGGING: true
136+
SIMULATE_CLUSTER: true
137+
ports:
138+
- "15379:15379"
139+
- "15380:15380"
140+
- "15381:15381"
141+
- "4000:4000"
142+
depends_on:
143+
- redis-proxied
144+
networks:
145+
- redis-net
146+
healthcheck:
147+
test: ["CMD", "sh", "-c", "wget -qO- http://localhost:4000/stats || exit 1"]
148+
interval: 10s
149+
timeout: 3s
150+
retries: 5

redis/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def __init__(
281281
if `True`, the response will be decoded to utf-8.
282282
Argument is ignored when connection_pool is provided.
283283
maint_notifications_config:
284-
configuration the pool to support maintenance notifications - see
284+
configures the pool to support maintenance notifications - see
285285
`redis.maint_notifications.MaintNotificationsConfig` for details.
286286
Only supported with RESP3
287287
If not provided and protocol is RESP3, the maintenance notifications

redis/cluster.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ def parse_cluster_myshardid(resp, **options):
197197
"username",
198198
"cache",
199199
"cache_config",
200+
"maint_notifications_config",
200201
)
201202
KWARGS_DISABLED_KEYS = ("host", "port", "retry")
202203

@@ -536,6 +537,7 @@ def __init__(
536537
cache_config: Optional[CacheConfig] = None,
537538
event_dispatcher: Optional[EventDispatcher] = None,
538539
policy_resolver: PolicyResolver = StaticPolicyResolver(),
540+
maint_notifications_config: Optional[MaintNotificationsConfig] = None,
539541
**kwargs,
540542
):
541543
"""
@@ -606,6 +608,13 @@ def __init__(
606608
which the nodes _think_ they are, to addresses at which a client may
607609
reach them, such as when they sit behind a proxy.
608610
611+
:param maint_notifications_config:
612+
Configures the nodes connections to support maintenance notifications - see
613+
`redis.maint_notifications.MaintNotificationsConfig` for details.
614+
Only supported with RESP3.
615+
If not provided and protocol is RESP3, the maintenance notifications
616+
will be enabled by default (logic is included in the NodesManager
617+
initialization).
609618
:**kwargs:
610619
Extra arguments that will be sent into Redis instance when created
611620
(See Official redis-py doc for supported kwargs - the only limitation
@@ -710,6 +719,7 @@ def __init__(
710719
cache=cache,
711720
cache_config=cache_config,
712721
event_dispatcher=self._event_dispatcher,
722+
maint_notifications_config=maint_notifications_config,
713723
**kwargs,
714724
)
715725

@@ -1629,6 +1639,9 @@ def __init__(
16291639
cache_config: Optional[CacheConfig] = None,
16301640
cache_factory: Optional[CacheFactoryInterface] = None,
16311641
event_dispatcher: Optional[EventDispatcher] = None,
1642+
maint_notifications_config: Optional[
1643+
MaintNotificationsConfig
1644+
] = MaintNotificationsConfig(),
16321645
**kwargs,
16331646
):
16341647
self.nodes_cache: Dict[str, Redis] = {}
@@ -1657,6 +1670,7 @@ def __init__(
16571670
self._credential_provider = self.connection_kwargs.get(
16581671
"credential_provider", None
16591672
)
1673+
self.maint_notifications_config = maint_notifications_config
16601674
self.initialize()
16611675

16621676
def get_node(self, host=None, port=None, node_name=None):
@@ -1804,7 +1818,10 @@ def create_redis_connections(self, nodes):
18041818
for node in nodes:
18051819
if node.redis_connection is None:
18061820
node.redis_connection = self.create_redis_node(
1807-
host=node.host, port=node.port, **self.connection_kwargs
1821+
host=node.host,
1822+
port=node.port,
1823+
maint_notifications_config=self.maint_notifications_config,
1824+
**self.connection_kwargs,
18081825
)
18091826
connection_pools.append(node.redis_connection.connection_pool)
18101827

@@ -1814,7 +1831,12 @@ def create_redis_connections(self, nodes):
18141831
)
18151832
)
18161833

1817-
def create_redis_node(self, host, port, **kwargs):
1834+
def create_redis_node(
1835+
self,
1836+
host,
1837+
port,
1838+
**kwargs,
1839+
):
18181840
# We are configuring the connection pool not to retry
18191841
# connections on lower level clients to avoid retrying
18201842
# connections to nodes that are not reachable
@@ -1828,13 +1850,8 @@ def create_redis_node(self, host, port, **kwargs):
18281850
backoff=NoBackoff(), retries=0, supported_errors=(ConnectionError,)
18291851
)
18301852

1831-
protocol = kwargs.get("protocol", None)
1832-
if protocol in [3, "3"]:
1833-
kwargs.update(
1834-
{"maint_notifications_config": MaintNotificationsConfig(enabled=False)}
1835-
)
18361853
if self.from_url:
1837-
# Create a redis node with a costumed connection pool
1854+
# Create a redis node with a custom connection pool
18381855
kwargs.update({"host": host})
18391856
kwargs.update({"port": port})
18401857
kwargs.update({"cache": self._cache})
@@ -1892,7 +1909,10 @@ def initialize(self):
18921909
else:
18931910
# Create a new Redis connection
18941911
r = self.create_redis_node(
1895-
startup_node.host, startup_node.port, **kwargs
1912+
startup_node.host,
1913+
startup_node.port,
1914+
maint_notifications_config=self.maint_notifications_config,
1915+
**kwargs,
18961916
)
18971917
self.startup_nodes[startup_node.name].redis_connection = r
18981918
# Make sure cluster mode is enabled on this node

0 commit comments

Comments
 (0)