Skip to content

Commit 19b55c6

Browse files
Fix: automatically close connection pool for async Sentinel (#2900)
* set the `auto_close_connection_pool` flag on Redis instance with its own pool. * Add tests for the Sentinel connection pool auto-close * auto_close_connection_pool is ignored if a pool is provided * linting
1 parent 6968431 commit 19b55c6

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

redis/asyncio/sentinel.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,15 @@ def master_for(
335335
kwargs["is_master"] = True
336336
connection_kwargs = dict(self.connection_kwargs)
337337
connection_kwargs.update(kwargs)
338-
return redis_class(
339-
connection_pool=connection_pool_class(
340-
service_name, self, **connection_kwargs
341-
)
338+
339+
connection_pool = connection_pool_class(service_name, self, **connection_kwargs)
340+
# The Redis object "owns" the pool
341+
auto_close_connection_pool = True
342+
client = redis_class(
343+
connection_pool=connection_pool,
342344
)
345+
client.auto_close_connection_pool = auto_close_connection_pool
346+
return client
343347

344348
def slave_for(
345349
self,
@@ -368,8 +372,12 @@ def slave_for(
368372
kwargs["is_master"] = False
369373
connection_kwargs = dict(self.connection_kwargs)
370374
connection_kwargs.update(kwargs)
371-
return redis_class(
372-
connection_pool=connection_pool_class(
373-
service_name, self, **connection_kwargs
374-
)
375+
376+
connection_pool = connection_pool_class(service_name, self, **connection_kwargs)
377+
# The Redis object "owns" the pool
378+
auto_close_connection_pool = True
379+
client = redis_class(
380+
connection_pool=connection_pool,
375381
)
382+
client.auto_close_connection_pool = auto_close_connection_pool
383+
return client

tests/test_asyncio/test_sentinel.py

+26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import socket
2+
from unittest import mock
23

34
import pytest
45
import pytest_asyncio
@@ -239,3 +240,28 @@ async def test_flushconfig(cluster, sentinel):
239240
async def test_reset(cluster, sentinel):
240241
cluster.master["is_odown"] = True
241242
assert await sentinel.sentinel_reset("mymaster")
243+
244+
245+
@pytest.mark.onlynoncluster
246+
@pytest.mark.parametrize("method_name", ["master_for", "slave_for"])
247+
async def test_auto_close_pool(cluster, sentinel, method_name):
248+
"""
249+
Check that the connection pool created by the sentinel client is
250+
automatically closed
251+
"""
252+
253+
method = getattr(sentinel, method_name)
254+
client = method("mymaster", db=9)
255+
pool = client.connection_pool
256+
assert client.auto_close_connection_pool is True
257+
calls = 0
258+
259+
async def mock_disconnect():
260+
nonlocal calls
261+
calls += 1
262+
263+
with mock.patch.object(pool, "disconnect", mock_disconnect):
264+
await client.close()
265+
266+
assert calls == 1
267+
await pool.disconnect()

0 commit comments

Comments
 (0)