bpo-34037, asyncio: add BaseEventLoop.wait_executor_on_close (GH-13786)

Add BaseEventLoop.wait_executor_on_close attribute: true by default.

loop.close() now waits for the default executor to finish by default.
Set loop.wait_executor_on_close attribute to False to not wait for
the executor.
This commit is contained in:
Victor Stinner 2019-06-03 23:31:04 +02:00 committed by GitHub
parent 78c7d52779
commit 0f0a30f4da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 3 deletions

View File

@ -140,12 +140,18 @@ Running and stopping the loop
The loop must not be running when this function is called. The loop must not be running when this function is called.
Any pending callbacks will be discarded. Any pending callbacks will be discarded.
This method clears all queues and shuts down the executor, but does This method clears all queues and shuts down the default executor. By
not wait for the executor to finish. default, it waits for the default executor to finish. Set
*loop.wait_executor_on_close* to ``False`` to not wait for the executor.
This method is idempotent and irreversible. No other methods This method is idempotent and irreversible. No other methods
should be called after the event loop is closed. should be called after the event loop is closed.
.. versionchanged:: 3.8
The method now waits for the default executor to finish by default.
Added *loop.wait_executor_on_close* attribute.
.. coroutinemethod:: loop.shutdown_asyncgens() .. coroutinemethod:: loop.shutdown_asyncgens()
Schedule all currently open :term:`asynchronous generator` objects to Schedule all currently open :term:`asynchronous generator` objects to

View File

@ -380,6 +380,8 @@ class Server(events.AbstractServer):
class BaseEventLoop(events.AbstractEventLoop): class BaseEventLoop(events.AbstractEventLoop):
def __init__(self): def __init__(self):
# If true, close() waits for the default executor to finish
self.wait_executor_on_close = True
self._timer_cancelled_count = 0 self._timer_cancelled_count = 0
self._closed = False self._closed = False
self._stopping = False self._stopping = False
@ -635,7 +637,7 @@ class BaseEventLoop(events.AbstractEventLoop):
executor = self._default_executor executor = self._default_executor
if executor is not None: if executor is not None:
self._default_executor = None self._default_executor = None
executor.shutdown(wait=False) executor.shutdown(wait=self.wait_executor_on_close)
def is_closed(self): def is_closed(self):
"""Returns True if the event loop was closed.""" """Returns True if the event loop was closed."""

View File

@ -0,0 +1,4 @@
:mod:`asyncio`: ``loop.close()`` now waits for the default executor to
finish by default. Set ``loop.wait_executor_on_close`` attribute to
``False`` to opt-in for Python 3.7 behavior (not wait for the executor to
finish).