From bcce75fa047d9137cd36ecd992f3f751db28fb4e Mon Sep 17 00:00:00 2001 From: Joseph Weston Date: Sat, 23 Nov 2019 17:26:12 +0100 Subject: [PATCH 1/3] replace BlockingRunner with AsyncRunner + asyncio.run This eliminates a lot of code duplication. We also deprecate the use of BlockingRunner directly. --- adaptive/runner.py | 94 ++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/adaptive/runner.py b/adaptive/runner.py index c0adebbf2..e55a5f78d 100644 --- a/adaptive/runner.py +++ b/adaptive/runner.py @@ -287,9 +287,29 @@ def _submit(self, x): pass -class BlockingRunner(BaseRunner): +def BlockingRunner( + learner, + goal, + *, + executor=None, + ntasks=None, + log=False, + shutdown_executor=False, + retries=0, + raise_if_retries_exceeded=True, +): """Run a learner synchronously in an executor. + **This runner is deprecated**, replace: + + >>> r = adaptive.BlockingRunner(...) + + with + + >>> import asyncio + >>> r = adaptive.Runner(...) + >>> asyncio.run(r) + Parameters ---------- learner : `~adaptive.BaseLearner` instance @@ -347,62 +367,30 @@ class BlockingRunner(BaseRunner): """ - def __init__( - self, + if inspect.iscoroutinefunction(learner.function): + raise ValueError("Coroutine functions can only be used " "with 'AsyncRunner'.") + warnings.warn( + "adaptive.BlockingRunner is deprecated, and will be removed in a " + "future version of adaptive.\n" + "Replace all uses of adaptive.BlockingRunner(...) with " + "asyncio.run(adaptive.Runner(...))", + DeprecationWarning, + ) + + r = AsyncRunner( learner, goal, - *, - executor=None, - ntasks=None, - log=False, - shutdown_executor=False, - retries=0, - raise_if_retries_exceeded=True, - ): - if inspect.iscoroutinefunction(learner.function): - raise ValueError( - "Coroutine functions can only be used " "with 'AsyncRunner'." - ) - super().__init__( - learner, - goal, - executor=executor, - ntasks=ntasks, - log=log, - shutdown_executor=shutdown_executor, - retries=retries, - raise_if_retries_exceeded=raise_if_retries_exceeded, - ) - self._run() - - def _submit(self, x): - return self.executor.submit(self.learner.function, x) + executor=executor, + ntasks=ntasks, + log=log, + shutdown_executor=shutdown_executor, + retries=retries, + raise_if_retries_exceeded=raise_if_retries_exceeded, + ) - def _run(self): - first_completed = concurrent.FIRST_COMPLETED + asyncio.run(r) - if self._get_max_tasks() < 1: - raise RuntimeError("Executor has no workers") - - try: - while not self.goal(self.learner): - futures = self._get_futures() - done, _ = concurrent.wait(futures, return_when=first_completed) - self._process_futures(done) - finally: - remaining = self._remove_unfinished() - if remaining: - concurrent.wait(remaining) - self._cleanup() - - def elapsed_time(self): - """Return the total time elapsed since the runner - was started.""" - if self.end_time is None: - # This shouldn't happen if the BlockingRunner - # correctly finished. - self.end_time = time.time() - return self.end_time - self.start_time + return r class AsyncRunner(BaseRunner): From c16e40f505342ea71ee6ce2556135339c6c26de5 Mon Sep 17 00:00:00 2001 From: Joseph Weston Date: Tue, 17 Dec 2019 15:06:48 +0100 Subject: [PATCH 2/3] remove use of asyncio.run This is a Python 3.7 feature, and in addition cannot be used with asyncio *tasks* (only coroutines). --- adaptive/runner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptive/runner.py b/adaptive/runner.py index e55a5f78d..bd2158864 100644 --- a/adaptive/runner.py +++ b/adaptive/runner.py @@ -308,7 +308,7 @@ def BlockingRunner( >>> import asyncio >>> r = adaptive.Runner(...) - >>> asyncio.run(r) + >>> asyncio.get_event_loop().run_until_complete(r.task) Parameters ---------- @@ -388,7 +388,7 @@ def BlockingRunner( raise_if_retries_exceeded=raise_if_retries_exceeded, ) - asyncio.run(r) + r.ioloop.run_until_complete(r.task) return r From 19f7992d96aa1f29f8241928c1603d5ec370a171 Mon Sep 17 00:00:00 2001 From: Joseph Weston Date: Tue, 17 Dec 2019 15:11:51 +0100 Subject: [PATCH 3/3] correct docstring --- adaptive/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptive/runner.py b/adaptive/runner.py index bd2158864..664a551c5 100644 --- a/adaptive/runner.py +++ b/adaptive/runner.py @@ -308,7 +308,7 @@ def BlockingRunner( >>> import asyncio >>> r = adaptive.Runner(...) - >>> asyncio.get_event_loop().run_until_complete(r.task) + >>> r.ioloop.run_until_complete(r.task) Parameters ----------