diff options
author | Pierre Ossman (ThinLinc team) <ossman@cendio.se> | 2024-03-11 20:43:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-11 12:43:30 -0700 |
commit | 1d0d49a7e86257ff95b4de0685e6997d7533993c (patch) | |
tree | 57b29921aa8502024674411fb495cc9dfaacaadd /Lib/asyncio/base_events.py | |
parent | 872c0714fcdc168ce4a69bdd0346f2d5dd488ec2 (diff) | |
download | cpython-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.py | 25 |
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' |