aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/asyncio/base_events.py
diff options
context:
space:
mode:
authorPierre Ossman (ThinLinc team) <ossman@cendio.se>2024-03-11 20:43:30 +0100
committerGitHub <noreply@github.com>2024-03-11 12:43:30 -0700
commit1d0d49a7e86257ff95b4de0685e6997d7533993c (patch)
tree57b29921aa8502024674411fb495cc9dfaacaadd /Lib/asyncio/base_events.py
parent872c0714fcdc168ce4a69bdd0346f2d5dd488ec2 (diff)
downloadcpython-1d0d49a7e86257ff95b4de0685e6997d7533993c.tar.gz
cpython-1d0d49a7e86257ff95b4de0685e6997d7533993c.zip
gh-113538: Add asycio.Server.{close,abort}_clients (#114432)
These give applications the option of more forcefully terminating client connections for asyncio servers. Useful when terminating a service and there is limited time to wait for clients to finish up their work.
Diffstat (limited to 'Lib/asyncio/base_events.py')
-rw-r--r--Lib/asyncio/base_events.py25
1 files changed, 17 insertions, 8 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 6c5cf28e7c5..f0e690b61a7 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -279,7 +279,9 @@ class Server(events.AbstractServer):
ssl_handshake_timeout, ssl_shutdown_timeout=None):
self._loop = loop
self._sockets = sockets
- self._active_count = 0
+ # Weak references so we don't break Transport's ability to
+ # detect abandoned transports
+ self._clients = weakref.WeakSet()
self._waiters = []
self._protocol_factory = protocol_factory
self._backlog = backlog
@@ -292,14 +294,13 @@ class Server(events.AbstractServer):
def __repr__(self):
return f'<{self.__class__.__name__} sockets={self.sockets!r}>'
- def _attach(self):
+ def _attach(self, transport):
assert self._sockets is not None
- self._active_count += 1
+ self._clients.add(transport)
- def _detach(self):
- assert self._active_count > 0
- self._active_count -= 1
- if self._active_count == 0 and self._sockets is None:
+ def _detach(self, transport):
+ self._clients.discard(transport)
+ if len(self._clients) == 0 and self._sockets is None:
self._wakeup()
def _wakeup(self):
@@ -348,9 +349,17 @@ class Server(events.AbstractServer):
self._serving_forever_fut.cancel()
self._serving_forever_fut = None
- if self._active_count == 0:
+ if len(self._clients) == 0:
self._wakeup()
+ def close_clients(self):
+ for transport in self._clients.copy():
+ transport.close()
+
+ def abort_clients(self):
+ for transport in self._clients.copy():
+ transport.abort()
+
async def start_serving(self):
self._start_serving()
# Skip one loop iteration so that all 'loop.add_reader'