Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH v2] EventLoop: add run_until_complete method (bug 591760)
Date: Mon, 22 Aug 2016 16:35:52
Message-Id: 1471883695-7991-1-git-send-email-zmedico@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH] EventLoop: add run_until_complete method (bug 591760) by Zac Medico
1 This emulates the asyncio.AbstractEventLoop.run_until_complete(future)
2 interface, which will make it possible to reduce latency in situations
3 where it is desirable for a loop to exit at the earliest opportunity.
4
5 The most tangible benefit of this change is that it provides a
6 migration path to asyncio, which will allow us to rely on a standard
7 library instead of our own internal event loop implementation.
8
9 In order to migrate to asyncio, more work is planned:
10
11 * Migrate all internal use of the EventLoop.iteration method to the new
12 run_until_complete(future) method, and remove the EventLoop.iteration
13 method (or make it private as long as it's needed to implement
14 run_until_complete for older python versions).
15
16 * Implement all EventLoop methods using asyncio.AbstractEventLoop
17 methods (but keep existing implementations for use with older python).
18
19 X-Gentoo-bug: 591760
20 X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=591760
21 ---
22 [PATCH v2] only updates the commit message to provide more context
23
24 pym/portage/tests/ebuild/test_ipc_daemon.py | 23 ++++++++++++++---------
25 pym/portage/util/_eventloop/EventLoop.py | 17 ++++++++++++++++-
26 2 files changed, 30 insertions(+), 10 deletions(-)
27
28 diff --git a/pym/portage/tests/ebuild/test_ipc_daemon.py b/pym/portage/tests/ebuild/test_ipc_daemon.py
29 index 835f51f..68f139a 100644
30 --- a/pym/portage/tests/ebuild/test_ipc_daemon.py
31 +++ b/pym/portage/tests/ebuild/test_ipc_daemon.py
32 @@ -1,4 +1,4 @@
33 -# Copyright 2010-2015 Gentoo Foundation
34 +# Copyright 2010-2016 Gentoo Foundation
35 # Distributed under the terms of the GNU General Public License v2
36
37 import tempfile
38 @@ -16,6 +16,7 @@ from portage.util import ensure_dirs
39 from portage.util._async.ForkProcess import ForkProcess
40 from portage.util._async.TaskScheduler import TaskScheduler
41 from portage.util._eventloop.global_event_loop import global_event_loop
42 +from portage.util.futures.futures import Future
43 from _emerge.SpawnProcess import SpawnProcess
44 from _emerge.EbuildBuildDir import EbuildBuildDir
45 from _emerge.EbuildIpcDaemon import EbuildIpcDaemon
46 @@ -140,19 +141,23 @@ class IpcDaemonTestCase(TestCase):
47 build_dir.unlock()
48 shutil.rmtree(tmpdir)
49
50 - def _timeout_callback(self):
51 - self._timed_out = True
52 + def _timeout_callback(self, task_scheduler):
53 + task_scheduler.cancel()
54 + self._exit_callback(task_scheduler)
55 +
56 + def _exit_callback(self, task_scheduler):
57 + if not self._run_done.done():
58 + self._run_done.set_result(True)
59
60 def _run(self, event_loop, task_scheduler, timeout):
61 - self._timed_out = False
62 - timeout_id = event_loop.timeout_add(timeout, self._timeout_callback)
63 + self._run_done = Future()
64 + timeout_id = event_loop.timeout_add(timeout,
65 + self._timeout_callback, task_scheduler)
66 + task_scheduler.addExitListener(self._exit_callback)
67
68 try:
69 task_scheduler.start()
70 - while not self._timed_out and task_scheduler.poll() is None:
71 - event_loop.iteration()
72 - if self._timed_out:
73 - task_scheduler.cancel()
74 + event_loop.run_until_complete(self._run_done)
75 task_scheduler.wait()
76 finally:
77 event_loop.source_remove(timeout_id)
78 diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py
79 index 8095400..8f13de3 100644
80 --- a/pym/portage/util/_eventloop/EventLoop.py
81 +++ b/pym/portage/util/_eventloop/EventLoop.py
82 @@ -1,4 +1,4 @@
83 -# Copyright 1999-2014 Gentoo Foundation
84 +# Copyright 1999-2016 Gentoo Foundation
85 # Distributed under the terms of the GNU General Public License v2
86
87 from __future__ import division
88 @@ -577,6 +577,21 @@ class EventLoop(object):
89 del self._poll_event_handlers[f]
90 return True
91
92 + def run_until_complete(self, future):
93 + """
94 + Run until the Future is done.
95 +
96 + @type future: asyncio.Future
97 + @param future: a Future to wait for
98 + @rtype: object
99 + @return: the Future's result
100 + @raise: the Future's exception
101 + """
102 + while not future.done():
103 + self.iteration()
104 +
105 + return future.result()
106 +
107 _can_poll_device = None
108
109 def can_poll_device():
110 --
111 2.7.4

Replies