Repository: aio-libs-abandoned/aioredis-py

Issue:
Sentinel pool discover doesn't take into account passed timeout
https://github.com/aio-libs/aioredis/blob/fd7411a8a6313c1844f615ef26902bb38fcc5c7b/aioredis/sentinel/pool.py#L44

https://github.com/aio-libs/aioredis/blob/fd7411a8a6313c1844f615ef26902bb38fcc5c7b/aioredis/sentinel/pool.py#L196



Discussion:
+1
Would you make a PR?

Resolving patch:
diff --git a/aioredis/sentinel/pool.py b/aioredis/sentinel/pool.py
--- a/aioredis/sentinel/pool.py
+++ b/aioredis/sentinel/pool.py
@@ -193,7 +193,7 @@ async def wait_closed(self):
         assert self._close_waiter is not None
         await asyncio.shield(self._close_waiter, loop=self._loop)
 
-    async def discover(self, timeout=0.2):    # TODO: better name?
+    async def discover(self, timeout=None):    # TODO: better name?
         """Discover sentinels and all monitored services within given timeout.
 
         If no sentinels discovered within timeout: TimeoutError is raised.
@@ -204,6 +204,8 @@ async def discover(self, timeout=0.2):    # TODO: better name?
         """
         # TODO: check not closed
         # TODO: discovery must be done with some customizable timeout.
+        if timeout is None:
+            timeout = self.discover_timeout
         tasks = []
         pools = []
         for addr in self._sentinels:    # iterate over unordered set


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -105,6 +105,8 @@ def create_sentinel(_closable, loop):
 
     async def f(*args, **kw):
         kw.setdefault('loop', loop)
+        # make it fail fast on slow CIs (if timeout argument is ommitted)
+        kw.setdefault('timeout', .001)
         client = await aioredis.sentinel.create_sentinel(*args, **kw)
         _closable(client)
         return client
@@ -132,7 +134,7 @@ def redis(create_redis, server, loop):
 def redis_sentinel(create_sentinel, sentinel, loop):
     """Returns Redis Sentinel client instance."""
     redis_sentinel = loop.run_until_complete(
-        create_sentinel([sentinel.tcp_address], loop=loop))
+        create_sentinel([sentinel.tcp_address], timeout=2, loop=loop))
     assert loop.run_until_complete(redis_sentinel.ping()) == b'PONG'
     return redis_sentinel
 
diff --git a/tests/sentinel_commands_test.py b/tests/sentinel_commands_test.py
--- a/tests/sentinel_commands_test.py
+++ b/tests/sentinel_commands_test.py
@@ -29,7 +29,8 @@ async def test_global_loop(sentinel, create_sentinel, loop):
     asyncio.set_event_loop(loop)
 
     # force global loop
-    client = await create_sentinel([sentinel.tcp_address], loop=None)
+    client = await create_sentinel([sentinel.tcp_address],
+                                   timeout=1, loop=None)
     assert client._pool._loop is loop
 
     asyncio.set_event_loop(None)
@@ -86,13 +87,13 @@ async def test_master__auth(create_sentinel, start_sentinel,
 
     sentinel = start_sentinel('auth_sentinel_1', master)
     client1 = await create_sentinel(
-        [sentinel.tcp_address], password='123', loop=loop)
+        [sentinel.tcp_address], password='123', timeout=1, loop=loop)
 
     client2 = await create_sentinel(
-        [sentinel.tcp_address], password='111', loop=loop)
+        [sentinel.tcp_address], password='111', timeout=1, loop=loop)
 
     client3 = await create_sentinel(
-        [sentinel.tcp_address], loop=loop)
+        [sentinel.tcp_address], timeout=1, loop=loop)
 
     m1 = client1.master_for(master.name)
     await m1.set('mykey', 'myval')
@@ -111,7 +112,7 @@ async def test_master__auth(create_sentinel, start_sentinel,
 @pytest.mark.run_loop
 async def test_master__no_auth(create_sentinel, sentinel, loop):
     client = await create_sentinel(
-        [sentinel.tcp_address], password='123', loop=loop)
+        [sentinel.tcp_address], password='123', timeout=1, loop=loop)
 
     master = client.master_for('masterA')
     with pytest.raises(MasterReplyError):
@@ -210,7 +211,8 @@ async def test_sentinels__exist(create_sentinel, start_sentinel,
     s2 = start_sentinel('peer-sentinel-2', m1, quorum=2, noslaves=True)
 
     redis_sentinel = await create_sentinel(
-        [s1.tcp_address, s2.tcp_address])
+        [s1.tcp_address, s2.tcp_address],
+        timeout=1)
 
     while True:
         info = await redis_sentinel.master('master-two-sentinels')
diff --git a/tests/sentinel_failover_test.py b/tests/sentinel_failover_test.py
--- a/tests/sentinel_failover_test.py
+++ b/tests/sentinel_failover_test.py
@@ -25,7 +25,8 @@ async def test_auto_failover(start_sentinel, start_server,
     sentinel2 = start_sentinel('sentinel-failover2', server1, quorum=2)
 
     sp = await create_sentinel([sentinel1.tcp_address,
-                                sentinel2.tcp_address])
+                                sentinel2.tcp_address],
+                               timeout=1)
 
     _, old_port = await sp.master_address(server1.name)
     # ignoring host
@@ -51,7 +52,7 @@ async def test_auto_failover(start_sentinel, start_server,
 
 @pytest.mark.run_loop
 async def test_sentinel_normal(sentinel, create_sentinel):
-    redis_sentinel = await create_sentinel([sentinel.tcp_address])
+    redis_sentinel = await create_sentinel([sentinel.tcp_address], timeout=1)
     redis = redis_sentinel.master_for('masterA')
 
     info = await redis.role()
@@ -72,7 +73,7 @@ async def test_sentinel_normal(sentinel, create_sentinel):
 @pytest.mark.xfail(reason="same sentinel; single master;")
 @pytest.mark.run_loop
 async def test_sentinel_slave(sentinel, create_sentinel):
-    redis_sentinel = await create_sentinel([sentinel.tcp_address])
+    redis_sentinel = await create_sentinel([sentinel.tcp_address], timeout=1)
     redis = redis_sentinel.slave_for('masterA')
 
     info = await redis.role()
@@ -92,7 +93,7 @@ async def test_sentinel_slave(sentinel, create_sentinel):
 @pytest.mark.xfail(reason="Need proper sentinel configuration")
 @pytest.mark.run_loop       # (timeout=600)
 async def test_sentinel_slave_fail(sentinel, create_sentinel, loop):
-    redis_sentinel = await create_sentinel([sentinel.tcp_address])
+    redis_sentinel = await create_sentinel([sentinel.tcp_address], timeout=1)
 
     key, field, value = b'key:hset', b'bar', b'zap'
 
@@ -128,7 +129,7 @@ async def test_sentinel_slave_fail(sentinel, create_sentinel, loop):
 @pytest.mark.xfail(reason="Need proper sentinel configuration")
 @pytest.mark.run_loop
 async def test_sentinel_normal_fail(sentinel, create_sentinel, loop):
-    redis_sentinel = await create_sentinel([sentinel.tcp_address])
+    redis_sentinel = await create_sentinel([sentinel.tcp_address], timeout=1)
 
     key, field, value = b'key:hset', b'bar', b'zap'
     redis = redis_sentinel.master_for('masterA')
@@ -161,7 +162,7 @@ async def test_sentinel_normal_fail(sentinel, create_sentinel, loop):
 @pytest.mark.run_loop
 async def test_failover_command(sentinel, create_sentinel, loop):
     master_name = 'masterA'
-    redis_sentinel = await create_sentinel([sentinel.tcp_address])
+    redis_sentinel = await create_sentinel([sentinel.tcp_address], timeout=1)
 
     orig_master = await redis_sentinel.master_address(master_name)
     ret = await redis_sentinel.failover(master_name)