MagicStack / MagicStack/uvloop

Server.serve_forever() isn't cancelled when Server.close() is called

Open
#602 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Cython
Stars
11.9k
Forks
616
PR merge metrics
No merged PRs in 30d

Description

  • uvloop version: 0.19.0
  • Python version: 3.10.12 (3.10.12-1~22.04.3)
  • Platform: Ubuntu 22.04.4
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?: Yes
  • Does uvloop behave differently from vanilla asyncio? How?: Yes, described below.

With stock asyncio, after awaiting on Server.serve_forever(), calling Server.close() causes the await statement to throw CancelledError. With uvloop's implementation, the listening socket is correctly closed, however the await statement blocks indefinitely.

Example:

async def run_server():
    async with await asyncio.start_server(lambda r,w: w.close(), '127.0.0.1', 8080) as server:
        server.get_loop().add_signal_handler(15, lambda: server.close())
        try:
            await server.serve_forever()
        except asyncio.CancelledError:
            print('Shutting down')

uvloop.run(run_server())

The uvloop version closes the listening socket in response to SIGTERM, but never exits. The stock version prints Shutting down and exits.

Here's the CPython source where this is implemented:

https://github.com/python/cpython/blob/v3.8.18/Lib/asyncio/base_events.py#L341-L344

Thanks for taking a look!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing uvloop's server behavior with the CPython implementation linked in Lib/asyncio/base_events.py around lines 341–344, focusing on Server.serve_forever() and Server.close(). Reproduce the issue with the provided SIGTERM example and confirm that closing the server causes serve_forever() to raise asyncio.CancelledError and print “Shutting down” before exiting.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.