Skip to content

serve_forever blocks upon cancellation when clients are connected (upstream change in CPython >= 3.12) #1608

Open
@pskopnik

Description

@pskopnik

An upstream change in CPython >= 3.12 changes the behaviour of asyncio.Server.serve_forever() to wait for all clients to disconnect voluntarily before returning upon cancellation. There is discussion to change this behaviour, but no patch has been finalized yet python/cpython#123720.

websockets is affected, because it relies directly on serve_forever(). Common patterns for running a server will start blocking in Python >= 3.12 upon cancellation until all clients disconnect.

  • serve() context manager + serve_forever(), described in the Quick examples.

    async with serve(hello, "localhost", 8765) as server:
        await server.serve_forever()

    This is the easiest to reproduce the problem: Create the script from the example, start the script, connect a client (any TCP client works, or a websockets client from same example page), then stop the server via Ctrl-C.

  • Plain serve() + serve_forever(), described in websockets.asyncio.server.serve API docs.

    server = await serve(handler, host, port)
    await server.serve_forever()

Waiting for an arbitrary future continues to work, also described in websockets.asyncio.server.serve docs. Upon cancellation, the serve() context manager is exited and will shut down the server including all connected clients.

async with serve(hello, "localhost", 8765) as server:
    await asyncio.get_running_loop().create_future()

Not sure how to continue here. This issue describes the problem and will hopefully save others the time to research. We could update all examples in the docs to use the only working pattern. Or add a note at least to server.serve mentioning the issue. To me it seems likely that the issue will be fixed in CPython and also backported to 3.12, so implementing a custom serve_forever() may not be worthwhile.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions