Skip to content

Commit 7f15281

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 65bde88 commit 7f15281

File tree

8 files changed

+668
-13
lines changed

8 files changed

+668
-13
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: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
---
22
# image tag 8.0-RC2-pre is the one matching the 8.0 GA release
33
x-client-libs-stack-image: &client-libs-stack-image
4-
image: "redislabs/client-libs-test:${CLIENT_LIBS_TEST_STACK_IMAGE_TAG:-8.4-RC1-pre.2}"
4+
image: "redislabs/client-libs-test:${CLIENT_LIBS_TEST_STACK_IMAGE_TAG:-8.4-GA-pre.2}"
55

66
x-client-libs-image: &client-libs-image
7-
image: "redislabs/client-libs-test:${CLIENT_LIBS_TEST_IMAGE_TAG:-8.4-RC1-pre.2}"
7+
image: "redislabs/client-libs-test:${CLIENT_LIBS_TEST_IMAGE_TAG:-8.4-GA-pre.2}"
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
@@ -196,6 +196,7 @@ def parse_cluster_myshardid(resp, **options):
196196
"username",
197197
"cache",
198198
"cache_config",
199+
"maint_notifications_config",
199200
)
200201
KWARGS_DISABLED_KEYS = ("host", "port", "retry")
201202

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

@@ -1622,6 +1632,9 @@ def __init__(
16221632
cache_config: Optional[CacheConfig] = None,
16231633
cache_factory: Optional[CacheFactoryInterface] = None,
16241634
event_dispatcher: Optional[EventDispatcher] = None,
1635+
maint_notifications_config: Optional[
1636+
MaintNotificationsConfig
1637+
] = MaintNotificationsConfig(),
16251638
**kwargs,
16261639
):
16271640
self.nodes_cache: Dict[str, Redis] = {}
@@ -1650,6 +1663,7 @@ def __init__(
16501663
self._credential_provider = self.connection_kwargs.get(
16511664
"credential_provider", None
16521665
)
1666+
self.maint_notifications_config = maint_notifications_config
16531667
self.initialize()
16541668

16551669
def get_node(self, host=None, port=None, node_name=None):
@@ -1797,7 +1811,10 @@ def create_redis_connections(self, nodes):
17971811
for node in nodes:
17981812
if node.redis_connection is None:
17991813
node.redis_connection = self.create_redis_node(
1800-
host=node.host, port=node.port, **self.connection_kwargs
1814+
host=node.host,
1815+
port=node.port,
1816+
maint_notifications_config=self.maint_notifications_config,
1817+
**self.connection_kwargs,
18011818
)
18021819
connection_pools.append(node.redis_connection.connection_pool)
18031820

@@ -1807,7 +1824,12 @@ def create_redis_connections(self, nodes):
18071824
)
18081825
)
18091826

1810-
def create_redis_node(self, host, port, **kwargs):
1827+
def create_redis_node(
1828+
self,
1829+
host,
1830+
port,
1831+
**kwargs,
1832+
):
18111833
# We are configuring the connection pool not to retry
18121834
# connections on lower level clients to avoid retrying
18131835
# connections to nodes that are not reachable
@@ -1821,13 +1843,8 @@ def create_redis_node(self, host, port, **kwargs):
18211843
backoff=NoBackoff(), retries=0, supported_errors=(ConnectionError,)
18221844
)
18231845

1824-
protocol = kwargs.get("protocol", None)
1825-
if protocol in [3, "3"]:
1826-
kwargs.update(
1827-
{"maint_notifications_config": MaintNotificationsConfig(enabled=False)}
1828-
)
18291846
if self.from_url:
1830-
# Create a redis node with a costumed connection pool
1847+
# Create a redis node with a custom connection pool
18311848
kwargs.update({"host": host})
18321849
kwargs.update({"port": port})
18331850
kwargs.update({"cache": self._cache})
@@ -1885,7 +1902,10 @@ def initialize(self):
18851902
else:
18861903
# Create a new Redis connection
18871904
r = self.create_redis_node(
1888-
startup_node.host, startup_node.port, **kwargs
1905+
startup_node.host,
1906+
startup_node.port,
1907+
maint_notifications_config=self.maint_notifications_config,
1908+
**kwargs,
18891909
)
18901910
self.startup_nodes[startup_node.name].redis_connection = r
18911911
# Make sure cluster mode is enabled on this node

0 commit comments

Comments
 (0)