Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: lib/_emerge/
Date: Tue, 18 Feb 2020 00:21:31
Message-Id: 1581984840.c7e52d0466211907d20cdbc04f1e90e7da626694.zmedico@gentoo
1 commit: c7e52d0466211907d20cdbc04f1e90e7da626694
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Mon Feb 17 23:39:12 2020 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Tue Feb 18 00:14:00 2020 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=c7e52d04
7
8 EbuildPhase: add _async_start coroutine
9
10 Convert the _start method to an _async_start coroutine, since
11 eventually this method will need to be a coroutine in order to write
12 messages to the build log as discussed in bug 709746.
13
14 Also convert SequentialTaskQueue to use the async_start method,
15 which is now required in order to start EbuildPhase instances.
16
17 Bug: https://bugs.gentoo.org/709746
18 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>
19
20 lib/_emerge/EbuildPhase.py | 21 +++++++++++----------
21 lib/_emerge/SequentialTaskQueue.py | 20 ++++++++++++++++----
22 2 files changed, 27 insertions(+), 14 deletions(-)
23
24 diff --git a/lib/_emerge/EbuildPhase.py b/lib/_emerge/EbuildPhase.py
25 index 234a273a0..63d0746da 100644
26 --- a/lib/_emerge/EbuildPhase.py
27 +++ b/lib/_emerge/EbuildPhase.py
28 @@ -23,7 +23,7 @@ from portage.util._dyn_libs.soname_deps_qa import (
29 )
30 from portage.package.ebuild.prepare_build_dirs import (_prepare_workdir,
31 _prepare_fake_distdir, _prepare_fake_filesdir)
32 -from portage.util.futures.compat_coroutine import coroutine
33 +from portage.util.futures.compat_coroutine import coroutine, coroutine_return
34 from portage.util import writemsg
35 from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
36 from portage.util.futures.executor.fork import ForkExecutor
37 @@ -69,6 +69,10 @@ class EbuildPhase(CompositeTask):
38 _locked_phases = ("setup", "preinst", "postinst", "prerm", "postrm")
39
40 def _start(self):
41 + self.scheduler.run_until_complete(self._async_start())
42 +
43 + @coroutine
44 + def _async_start(self):
45
46 need_builddir = self.phase not in EbuildProcess._phases_without_builddir
47
48 @@ -138,20 +142,17 @@ class EbuildPhase(CompositeTask):
49 env_extractor = BinpkgEnvExtractor(background=self.background,
50 scheduler=self.scheduler, settings=self.settings)
51 if env_extractor.saved_env_exists():
52 - self._start_task(env_extractor, self._env_extractor_exit)
53 - return
54 + self._current_task = env_extractor
55 + yield env_extractor.async_start()
56 + yield env_extractor.async_wait()
57 + if self._default_exit(env_extractor) != os.EX_OK:
58 + self._async_wait()
59 + coroutine_return()
60 # If the environment.bz2 doesn't exist, then ebuild.sh will
61 # source the ebuild as a fallback.
62
63 self._start_lock()
64
65 - def _env_extractor_exit(self, env_extractor):
66 - if self._default_exit(env_extractor) != os.EX_OK:
67 - self.wait()
68 - return
69 -
70 - self._start_lock()
71 -
72 def _start_lock(self):
73 if (self.phase in self._locked_phases and
74 "ebuild-locks" in self.settings.features):
75
76 diff --git a/lib/_emerge/SequentialTaskQueue.py b/lib/_emerge/SequentialTaskQueue.py
77 index 80908936c..a4555275f 100644
78 --- a/lib/_emerge/SequentialTaskQueue.py
79 +++ b/lib/_emerge/SequentialTaskQueue.py
80 @@ -1,9 +1,12 @@
81 -# Copyright 1999-2012 Gentoo Foundation
82 +# Copyright 1999-2020 Gentoo Authors
83 # Distributed under the terms of the GNU General Public License v2
84
85 from collections import deque
86 +import functools
87 import sys
88
89 +from portage.util.futures import asyncio
90 +from portage.util.futures.compat_coroutine import coroutine
91 from portage.util.SlotObject import SlotObject
92
93 class SequentialTaskQueue(SlotObject):
94 @@ -41,18 +44,27 @@ class SequentialTaskQueue(SlotObject):
95 cancelled = getattr(task, "cancelled", None)
96 if not cancelled:
97 self.running_tasks.add(task)
98 - task.addExitListener(self._task_exit)
99 - task.start()
100 + future = asyncio.ensure_future(self._task_coroutine(task), loop=task.scheduler)
101 + future.add_done_callback(functools.partial(self._task_exit, task))
102 finally:
103 self._scheduling = False
104
105 - def _task_exit(self, task):
106 + @coroutine
107 + def _task_coroutine(self, task):
108 + yield task.async_start()
109 + yield task.async_wait()
110 +
111 + def _task_exit(self, task, future):
112 """
113 Since we can always rely on exit listeners being called, the set of
114 running tasks is always pruned automatically and there is never any need
115 to actively prune it.
116 """
117 self.running_tasks.remove(task)
118 + try:
119 + future.result()
120 + except asyncio.CancelledError:
121 + self.clear()
122 if self._task_queue:
123 self.schedule()