This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Server.wait_closed() doesn't always wait for its transports to fihish
Type: Stage:
Components: asyncio Versions: Python 3.8, Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, aymeric.augustin, tmewett, yselivanov
Priority: normal Keywords:

Created on 2018-06-01 05:11 by yselivanov, last changed 2022-04-11 14:59 by admin.

Messages (3)
msg318360 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2018-06-01 05:11
Server.wait_closed() currently does two checks:

1. if _sockets is None -- means that Server.close() was called
2. if self._waiters is None -- means that Server._wakeup() was called

if (1) *or* (2) is true, wait_closed() just returns without waiting on anything.

However, when Server.close() is called there might be still active transports serving requests.  Server.wait_closed() should wait until all of them are detached, even if Server._sockets is already reset.

So the below implementation:

    async def wait_closed(self):
        if self._sockets is None or self._waiters is None:
            return
        waiter = self._loop.create_future()
        self._waiters.append(waiter)
        await waiter

should be changed to:

    async def wait_closed(self):
        if self._waiters is None:
            assert self._active_count == 0
            return
        waiter = self._loop.create_future()
        self._waiters.append(waiter)
        await waiter
msg326724 - (view) Author: Aymeric Augustin (aymeric.augustin) * Date: 2018-09-30 13:50
I believe this is by design: the documentation says:

> The sockets that represent existing incoming client connections are left open.

`Server` doesn't keep track of active transports serving requests.

(That said, I haven't figured out what _waiters is here so I could be wrong.)
msg375406 - (view) Author: Tom (tmewett) Date: 2020-08-14 13:48
I ran into this while working on an asyncio application using
asyncio.start_server.

From the documentation, I expected the combination of `close` and `wait_closed`
to wait until all connection handlers have finished. Instead, handlers remaining
running with open connections as background tasks. I wanted to be able to
"gracefully" close the server, with all processing done, so I could inspect some
results for a test case.

Could there be a method for this? One suggestion would be:

*   Clarify the current behaviour of `close` and `wait_closed`
    (https://bugs.python.org/issue34852)
*   Add new coro `wait_finished` which waits until all handler tasks are done

I'm afraid I'm not familiar with low-level asyncio APIs like transports and
protocols, so I don't know how/if this fits in with those.
History
Date User Action Args
2022-04-11 14:59:01adminsetgithub: 77908
2020-08-14 13:48:19tmewettsetnosy: + tmewett
messages: + msg375406
2018-09-30 13:50:09aymeric.augustinsetnosy: + aymeric.augustin
messages: + msg326724
2018-06-01 05:11:49yselivanovcreate