The issue fixed in #111424 is only available in Python 3.12. As a result, the example below prematurely closes a connection when using an older Python version. The old behavior may lead to bugs that are hard to catch, and the difference in behavior implies that applications must use workarounds to support multiple Python versions.
If backporting the fix is not an option, it would be helpful to add a note to the documentation of asyncio.Server.wait_closed that it changed in Python 3.12.
Related issues: #104344 (same cause, going from 3.11 to 3.12), #79033
This is a minimal working example distilled from a more complex use case where the stop_event is set in a function that receives the request and creates the response.
One possible workaround is to postpone setting the stop_event to the end of the handler function. That would be easy in this example, but more involved in the case where I ran into this issue.
Python 3.12 and 3.13 output
server.py
Starting server
Server listening at: socket
Client connected
Received: Hello
----> Respond with same message <----
----> Closing connection <----
Client connected
Received: STOP
Client requests stop. Setting stop event
Server stopping
----> Respond with same message <----
----> Closing connection <----
Server stopped
client.py
Starting client
Connecting to: socket
Connected
Sending message: Hello
Received response: Hello
Closing connection
Connecting to: socket
Connected
Sending message: STOP
Received response: STOP
Closing connection
Stopping client
Python 3.9, 3.10 and 3.11 output
Note that the handler does not complete when it receives STOP.
server.py
Starting server
Server listening at: socket
Client connected
Received: Hello
----> Respond with same message <----
----> Closing connection <----
Client connected
Received: STOP
Client requests stop. Setting stop event
Server stopping
Server stopped
client.py
Starting client
Connecting to: socket
Connected
Sending message: Hello
Received response: Hello
Closing connection
Connecting to: socket
Connected
Sending message: STOP
Received response:
Closing connection
Stopping client
Here is a workaround that mimics the implementation in Python 3.12.1 when using a Python version without the fix in #111424. One can add the following code right before print("Server stopped") in server.py:
ifsys.version_info< (3, 12, 1) andserver._waitersisnotNone:
# Workaround for server.wait_closed() issue fixed in Python 3.12.1waiter=server.get_loop().create_future()
server._waiters.append(waiter)
awaitwaiter
This may be a useful snippet for implementing a server that should work across different Python versions.
Activity
tovrstra commented on Jun 22, 2024
Here is a workaround that mimics the implementation in Python 3.12.1 when using a Python version without the fix in #111424. One can add the following code right before print("Server stopped") in server.py:
This may be a useful snippet for implementing a server that should work across different Python versions.
Fix SSH server shutdown with active clients
Fix SSH server shutdown with active clients
pythongh-120866: Document behavior change of asyncio.Server.wait_clos…
pythongh-120866: Document behavior change of asyncio.Server.wait_clos…
gh-120866: Document behavior change of asyncio.Server.wait_closed() s…
[3.13] gh-120866: Document behavior change of asyncio.Server.wait_clo…
[3.14] gh-120866: Document behavior change of asyncio.Server.wait_clo…
[3.15] gh-120866: Document behavior change of asyncio.Server.wait_clo…
pythongh-120866: Document behavior change of asyncio.Server.wait_clos…