Skip to content

Commit 1ca3e8b

Browse files
committed
add closing() context manager, which by default does a shutdown(wait=False) for better performance in async
1 parent 3b52ee3 commit 1ca3e8b

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

examples/executor_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async def master():
1616

1717
await first_50(progress)
1818
loop = asyncio.get_running_loop()
19-
with QThreadExecutor(1) as exec:
19+
with QThreadExecutor(1).closing() as exec:
2020
await loop.run_in_executor(exec, functools.partial(last_50, progress), loop)
2121

2222

src/qasync/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,14 @@ def __enter__(self, *args):
258258
def __exit__(self, *args):
259259
self.shutdown()
260260

261+
@contextlib.contextmanager
262+
def closing(self, *, wait=False, cancel_futures=False):
263+
"""Explicit context manager to do shutdown, with Wait=False by default"""
264+
try:
265+
yield self
266+
finally:
267+
self.shutdown(wait=wait, cancel_futures=cancel_futures)
268+
261269

262270
def _result_or_cancel(fut, timeout=None):
263271
try:

tests/test_qthreadexec.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import time
88
import weakref
99
from concurrent.futures import CancelledError, TimeoutError
10+
from unittest import mock
1011

1112
import pytest
1213

@@ -175,3 +176,21 @@ def func(x):
175176
# because the max number of workers is 5 and the rest of
176177
# the tasks were not started at the time of the cancel.
177178
assert set(results) != {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
179+
180+
181+
def test_closing(executor):
182+
"""Test that closing context manager works as expected"""
183+
# mock the shutdown method of the executor
184+
with mock.patch.object(executor, "shutdown") as mock_shutdown:
185+
with executor.closing():
186+
pass
187+
188+
# ensure that shutdown was called with (False, cancel_futures=False)
189+
mock_shutdown.assert_called_once_with(wait=False, cancel_futures=False)
190+
191+
with mock.patch.object(executor, "shutdown") as mock_shutdown:
192+
with executor.closing(wait=True, cancel_futures=True):
193+
pass
194+
195+
# ensure that shutdown was called with (False, cancel_futures=False)
196+
mock_shutdown.assert_called_once_with(wait=True, cancel_futures=True)

0 commit comments

Comments
 (0)