From 995f0f983386e2a82dbce65d4366ee7f58f59138 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 20 Aug 2016 14:59:55 -0700 Subject: EventLoop: add run_until_complete method (bug 591760) This emulates the asyncio.AbstractEventLoop.run_until_complete(future) interface, which will make it possible to reduce latency in situations where it is desirable for a loop to exit at the earliest opportunity. The most tangible benefit of this change is that it provides a migration path to asyncio, which will allow us to rely on a standard library instead of our own internal event loop implementation. In order to migrate to asyncio, more work is planned: * Migrate all internal use of the EventLoop.iteration method to the new run_until_complete(future) method, and remove the EventLoop.iteration method (or make it private as long as it's needed to implement run_until_complete for older python versions). * Implement all EventLoop methods using asyncio.AbstractEventLoop methods (but keep existing implementations for use with older python). X-Gentoo-bug: 591760 X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=591760 Acked-by: Alexander Berntsen --- pym/portage/tests/ebuild/test_ipc_daemon.py | 23 ++++++++++++++--------- pym/portage/util/_eventloop/EventLoop.py | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/pym/portage/tests/ebuild/test_ipc_daemon.py b/pym/portage/tests/ebuild/test_ipc_daemon.py index 835f51f80..68f139aa4 100644 --- a/pym/portage/tests/ebuild/test_ipc_daemon.py +++ b/pym/portage/tests/ebuild/test_ipc_daemon.py @@ -1,4 +1,4 @@ -# Copyright 2010-2015 Gentoo Foundation +# Copyright 2010-2016 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import tempfile @@ -16,6 +16,7 @@ from portage.util import ensure_dirs from portage.util._async.ForkProcess import ForkProcess from portage.util._async.TaskScheduler import TaskScheduler from portage.util._eventloop.global_event_loop import global_event_loop +from portage.util.futures.futures import Future from _emerge.SpawnProcess import SpawnProcess from _emerge.EbuildBuildDir import EbuildBuildDir from _emerge.EbuildIpcDaemon import EbuildIpcDaemon @@ -140,19 +141,23 @@ class IpcDaemonTestCase(TestCase): build_dir.unlock() shutil.rmtree(tmpdir) - def _timeout_callback(self): - self._timed_out = True + def _timeout_callback(self, task_scheduler): + task_scheduler.cancel() + self._exit_callback(task_scheduler) + + def _exit_callback(self, task_scheduler): + if not self._run_done.done(): + self._run_done.set_result(True) def _run(self, event_loop, task_scheduler, timeout): - self._timed_out = False - timeout_id = event_loop.timeout_add(timeout, self._timeout_callback) + self._run_done = Future() + timeout_id = event_loop.timeout_add(timeout, + self._timeout_callback, task_scheduler) + task_scheduler.addExitListener(self._exit_callback) try: task_scheduler.start() - while not self._timed_out and task_scheduler.poll() is None: - event_loop.iteration() - if self._timed_out: - task_scheduler.cancel() + event_loop.run_until_complete(self._run_done) task_scheduler.wait() finally: event_loop.source_remove(timeout_id) diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py index 809540023..8f13de377 100644 --- a/pym/portage/util/_eventloop/EventLoop.py +++ b/pym/portage/util/_eventloop/EventLoop.py @@ -1,4 +1,4 @@ -# Copyright 1999-2014 Gentoo Foundation +# Copyright 1999-2016 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import division @@ -577,6 +577,21 @@ class EventLoop(object): del self._poll_event_handlers[f] return True + def run_until_complete(self, future): + """ + Run until the Future is done. + + @type future: asyncio.Future + @param future: a Future to wait for + @rtype: object + @return: the Future's result + @raise: the Future's exception + """ + while not future.done(): + self.iteration() + + return future.result() + _can_poll_device = None def can_poll_device(): -- cgit v1.2.3-65-gdbad