8
8
import asyncio
9
9
import functools
10
10
import inspect
11
+ import logging
11
12
import time
12
13
import warnings
13
14
16
17
from . import exceptions
17
18
18
19
20
+ logger = logging .getLogger (__name__ )
21
+
22
+
19
23
class PoolConnectionProxyMeta (type ):
20
24
21
25
def __new__ (mcls , name , bases , dct , * , wrap = False ):
@@ -621,7 +625,10 @@ async def close(self):
621
625
Wait until all pool connections are released, close them and
622
626
shut down the pool. If any error (including cancellation) occurs
623
627
in ``close()`` the pool will terminate by calling
624
- :meth:'Pool.terminate() <pool.Pool.terminate>`.
628
+ :meth:`Pool.terminate() <pool.Pool.terminate>`.
629
+
630
+ It is advisable to use :func:`python:asyncio.wait_for` to set
631
+ a timeout.
625
632
626
633
.. versionchanged:: 0.16.0
627
634
``close()`` now waits until all pool connections are released
@@ -635,6 +642,9 @@ async def close(self):
635
642
self ._closing = True
636
643
637
644
try :
645
+ warning_callback = self ._loop .call_later (
646
+ 60 , self ._warn_on_long_close )
647
+
638
648
release_coros = [
639
649
ch .wait_until_released () for ch in self ._holders ]
640
650
await asyncio .gather (* release_coros , loop = self ._loop )
@@ -648,9 +658,16 @@ async def close(self):
648
658
raise
649
659
650
660
finally :
661
+ warning_callback .cancel ()
651
662
self ._closed = True
652
663
self ._closing = False
653
664
665
+ def _warn_on_long_close (self ):
666
+ logger .warning ('Pool.close() is taking over 60 seconds to complete. '
667
+ 'Check if you have any unreleased connections left. '
668
+ 'Use asyncio.wait_for() to set a timeout for '
669
+ 'Pool.close().' )
670
+
654
671
def terminate (self ):
655
672
"""Terminate all connections in the pool."""
656
673
if self ._closed :
0 commit comments