Skip to content

Add Server.close_clients() and Server.abort_clients() - #782

Open
ybai08 wants to merge 1 commit into
MagicStack:masterfrom
ybai08:server-close-clients
Open

ybai08 wants to merge 1 commit into
MagicStack:masterfrom
ybai08:server-close-clients

Conversation

@ybai08

@ybai08 ybai08 commented Oct 18, 2026

Copy link
Copy Markdown

Fixes #683.

Python 3.13 added Server.close_clients() and Server.abort_clients() to asyncio, but uvloop.loop.Server doesn't have them: AttributeError: 'uvloop.loop.Server' object has no attribute 'close_clients'.

The server now keeps its client transports in a WeakSet (as asyncio's Server._clients does), next to the existing _active_count. _attach() / _detach() take the transport, and the two new methods call close() / abort() on a snapshot of that set. The methods exist on every Python version uvloop supports, not just 3.13+. wait_closed() keeps its current behaviour.

Tests: test_server_close_clients / test_server_abort_clients in tests/test_tcp.py start a server with three connected clients and call srv.close(). They check that the connections stay open, then call the new method and check that every client sees EOF (or a reset for abort_clients) and every handler finishes. The asyncio variants are skipped before 3.13.

Testing (macOS arm64, built with --use-system-libuv against Homebrew libuv 1.53.0):

  • With the source files reverted to master, both Test_UV_TCP tests fail on 3.13: AttributeError: 'uvloop.loop.Server' object has no attribute 'close_clients' (and the same for abort_clients). The Test_AIO_TCP variants pass.
  • With the change, all four pass on 3.13, and the uvloop ones pass on 3.12.
  • The suite was run with python -m unittest discover tests on 3.12 and 3.13, and with PYTHONASYNCIODEBUG=1 on 3.13: 531 tests each. The only failure is test_fs_event_rename (FSEvents reports CHANGE instead of RENAME on this machine). It fails the same way in a tree without this change.
  • flake8 passes.

Not run: Linux, the free-threaded build, the bundled-libuv build, and benchmarks. The accept path now does one WeakSet.add() and one discard() per connection.

Python 3.13 added close_clients() and abort_clients() to asyncio.Server,
to close (or abort) the connections accepted by a server, but
uvloop.loop.Server did not have them and raised AttributeError.

Keep track of the server's client transports in a WeakSet (as asyncio
does) next to the existing active connection count, and implement both
methods on top of it.

Fixes MagicStack#683.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python3.13 support - close_clients

1 participant