Skip to content

Commit 4e767c5

Browse files
committed
fix: Add warning if relying on Redis max_connections parameter
The `new_feature_store` and `new_big_segment_store` methods accept a `max_connections` parameter that has been unused since v8. We cannot start using this parameter now as it would be a functionally breaking change. Instead, we are opting to warn customers who might try setting it explicitly. fixes #386
1 parent 45786a9 commit 4e767c5

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

ldclient/integrations/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from threading import Event
77
from typing import Any, Callable, Dict, List, Mapping, Optional
88

9+
from ldclient import log
910
from ldclient.config import Builder, Config
1011
from ldclient.feature_store import CacheConfig
1112
from ldclient.feature_store_helpers import CachingStoreWrapper
@@ -168,12 +169,21 @@ def new_feature_store(
168169
:param url: the URL of the Redis host; defaults to ``DEFAULT_URL``
169170
:param prefix: a namespace prefix to be prepended to all Redis keys; defaults to
170171
``DEFAULT_PREFIX``
172+
:param max_connections: (deprecated and unused) This parameter is not used. To configure
173+
the maximum number of connections, use ``redis_opts={'max_connections': N}`` instead.
171174
:param caching: specifies whether local caching should be enabled and if so,
172175
sets the cache properties; defaults to :func:`ldclient.feature_store.CacheConfig.default()`
173176
:param redis_opts: extra options for initializing Redis connection from the url,
174177
see `redis.connection.ConnectionPool.from_url` for more details.
175178
"""
176179

180+
if max_connections != Redis.DEFAULT_MAX_CONNECTIONS:
181+
log.warning(
182+
"The max_connections parameter is not used and will be removed in a future version. "
183+
"Please set max_connections in redis_opts instead, e.g., redis_opts={'max_connections': %d}",
184+
max_connections
185+
)
186+
177187
core = _RedisFeatureStoreCore(url, prefix, redis_opts)
178188
wrapper = CachingStoreWrapper(core, caching)
179189
wrapper._core = core # exposed for testing
@@ -200,10 +210,19 @@ def new_big_segment_store(url: str = 'redis://localhost:6379/0', prefix: str = '
200210
:param url: the URL of the Redis host; defaults to ``DEFAULT_URL``
201211
:param prefix: a namespace prefix to be prepended to all Redis keys; defaults to
202212
``DEFAULT_PREFIX``
213+
:param max_connections: (deprecated and unused) This parameter is not used. To configure
214+
the maximum number of connections, use ``redis_opts={'max_connections': N}`` instead.
203215
:param redis_opts: extra options for initializing Redis connection from the url,
204216
see `redis.connection.ConnectionPool.from_url` for more details.
205217
"""
206218

219+
if max_connections != Redis.DEFAULT_MAX_CONNECTIONS:
220+
log.warning(
221+
"The max_connections parameter is not used and will be removed in a future version. "
222+
"Please set max_connections in redis_opts instead, e.g., redis_opts={'max_connections': %d}",
223+
max_connections
224+
)
225+
207226
return _RedisBigSegmentStore(url, prefix, redis_opts)
208227

209228

ldclient/testing/integrations/test_redis.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,85 @@ class TestRedisBigSegmentStore(BigSegmentStoreTestBase):
125125
@property
126126
def tester_class(self):
127127
return RedisBigSegmentStoreTester
128+
129+
130+
@pytest.mark.skipif(skip_database_tests, reason="skipping database tests")
131+
def test_feature_store_max_connections_is_not_used():
132+
"""Test that the max_connections parameter is NOT passed to the Redis connection pool."""
133+
custom_max_connections = 42
134+
store = Redis.new_feature_store(max_connections=custom_max_connections)
135+
136+
# Access the connection pool through the wrapper's core
137+
actual_max_connections = store._core._pool.max_connections
138+
139+
# Should NOT be our custom value since the parameter is unused
140+
assert actual_max_connections != custom_max_connections, \
141+
f"Expected max_connections to NOT be {custom_max_connections}, but it was set"
142+
143+
144+
@pytest.mark.skipif(skip_database_tests, reason="skipping database tests")
145+
def test_big_segment_store_max_connections_is_not_used():
146+
"""Test that the max_connections parameter is NOT passed to the Redis connection pool."""
147+
custom_max_connections = 42
148+
store = Redis.new_big_segment_store(max_connections=custom_max_connections)
149+
150+
# Access the connection pool directly from the store
151+
actual_max_connections = store._pool.max_connections
152+
153+
# Should NOT be our custom value since the parameter is unused
154+
assert actual_max_connections != custom_max_connections, \
155+
f"Expected max_connections to NOT be {custom_max_connections}, but it was set"
156+
157+
158+
@pytest.mark.skipif(skip_database_tests, reason="skipping database tests")
159+
def test_feature_store_max_connections_warns_when_non_default(caplog):
160+
"""Test that a warning is logged when max_connections differs from the default."""
161+
import logging
162+
caplog.set_level(logging.WARNING)
163+
164+
custom_max_connections = 42
165+
Redis.new_feature_store(max_connections=custom_max_connections)
166+
167+
assert any("max_connections parameter is not used" in record.message for record in caplog.records), \
168+
"Expected warning that parameter is not used"
169+
assert any("redis_opts" in record.message for record in caplog.records), \
170+
"Expected warning to mention redis_opts"
171+
172+
173+
@pytest.mark.skipif(skip_database_tests, reason="skipping database tests")
174+
def test_big_segment_store_max_connections_warns_when_non_default(caplog):
175+
"""Test that a warning is logged when max_connections differs from the default."""
176+
import logging
177+
caplog.set_level(logging.WARNING)
178+
179+
custom_max_connections = 42
180+
Redis.new_big_segment_store(max_connections=custom_max_connections)
181+
182+
assert any("max_connections parameter is not used" in record.message for record in caplog.records), \
183+
"Expected warning that parameter is not used"
184+
assert any("redis_opts" in record.message for record in caplog.records), \
185+
"Expected warning to mention redis_opts"
186+
187+
188+
@pytest.mark.skipif(skip_database_tests, reason="skipping database tests")
189+
def test_feature_store_max_connections_no_warn_when_default(caplog):
190+
"""Test that no warning is logged when max_connections is the default value."""
191+
import logging
192+
caplog.set_level(logging.WARNING)
193+
194+
Redis.new_feature_store(max_connections=Redis.DEFAULT_MAX_CONNECTIONS)
195+
196+
assert not any("max_connections parameter is not used" in record.message for record in caplog.records), \
197+
"Expected no warning when using default value"
198+
199+
200+
@pytest.mark.skipif(skip_database_tests, reason="skipping database tests")
201+
def test_big_segment_store_max_connections_no_warn_when_default(caplog):
202+
"""Test that no warning is logged when max_connections is the default value."""
203+
import logging
204+
caplog.set_level(logging.WARNING)
205+
206+
Redis.new_big_segment_store(max_connections=Redis.DEFAULT_MAX_CONNECTIONS)
207+
208+
assert not any("max_connections parameter is not used" in record.message for record in caplog.records), \
209+
"Expected no warning when using default value"

0 commit comments

Comments
 (0)