Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/_emerge/, pym/portage/_emirrordist/
Date: Wed, 06 Jun 2018 02:22:46
Message-Id: 1528250995.937d0156aa060bdba9095313dedbb62e0a993aea.zmedico@gentoo
1 commit: 937d0156aa060bdba9095313dedbb62e0a993aea
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Wed Jun 6 01:52:59 2018 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Wed Jun 6 02:09:55 2018 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=937d0156
7
8 CompositeTask: handle SIGINT/TERM cancelled futures (bug 657436)
9
10 In order to avoid raising an unwanted CancelledError, make
11 CompositeTask check for cancelled futures before attempting
12 to call future.result(). The intention is only to handle
13 failures triggered by SIGINT/TERM, since other types of
14 expected failures should always be handled by catching the
15 exception raised from future.result().
16
17 Bug: https://bugs.gentoo.org/657436
18
19 pym/_emerge/Binpkg.py | 10 +++++++++-
20 pym/_emerge/BinpkgFetcher.py | 8 ++++++++
21 pym/_emerge/CompositeTask.py | 1 +
22 pym/_emerge/EbuildBuild.py | 16 ++++++++++++++++
23 pym/_emerge/EbuildFetcher.py | 12 ++++++++++++
24 pym/_emerge/EbuildPhase.py | 4 ++++
25 pym/_emerge/PackageUninstall.py | 8 ++++++++
26 pym/portage/_emirrordist/FetchIterator.py | 10 ++++++++++
27 8 files changed, 68 insertions(+), 1 deletion(-)
28
29 diff --git a/pym/_emerge/Binpkg.py b/pym/_emerge/Binpkg.py
30 index 2b67816e8..7791ec236 100644
31 --- a/pym/_emerge/Binpkg.py
32 +++ b/pym/_emerge/Binpkg.py
33 @@ -122,6 +122,10 @@ class Binpkg(CompositeTask):
34 def _start_fetcher(self, lock_task=None):
35 if lock_task is not None:
36 self._assert_current(lock_task)
37 + if lock_task.cancelled:
38 + self._default_final_exit(lock_task)
39 + return
40 +
41 lock_task.future.result()
42 # Initialize PORTAGE_LOG_FILE (clean_log won't work without it).
43 portage.prepare_build_dirs(self.settings["ROOT"], self.settings, 1)
44 @@ -411,8 +415,12 @@ class Binpkg(CompositeTask):
45
46 def _unlock_builddir_exit(self, unlock_task, returncode=None):
47 self._assert_current(unlock_task)
48 + if unlock_task.cancelled and returncode is not None:
49 + self._default_final_exit(unlock_task)
50 + return
51 +
52 # Normally, async_unlock should not raise an exception here.
53 - unlock_task.future.result()
54 + unlock_task.future.cancelled() or unlock_task.future.result()
55 if returncode is not None:
56 self.returncode = returncode
57 self._async_wait()
58
59 diff --git a/pym/_emerge/BinpkgFetcher.py b/pym/_emerge/BinpkgFetcher.py
60 index 8e651a1c7..36d027de3 100644
61 --- a/pym/_emerge/BinpkgFetcher.py
62 +++ b/pym/_emerge/BinpkgFetcher.py
63 @@ -48,6 +48,10 @@ class BinpkgFetcher(CompositeTask):
64
65 def _start_locked(self, fetcher, lock_task):
66 self._assert_current(lock_task)
67 + if lock_task.cancelled:
68 + self._default_final_exit(lock_task)
69 + return
70 +
71 lock_task.future.result()
72 self._start_task(fetcher, self._fetcher_exit)
73
74 @@ -65,6 +69,10 @@ class BinpkgFetcher(CompositeTask):
75 def _fetcher_exit_unlocked(self, fetcher, unlock_task=None):
76 if unlock_task is not None:
77 self._assert_current(unlock_task)
78 + if unlock_task.cancelled:
79 + self._default_final_exit(unlock_task)
80 + return
81 +
82 unlock_task.future.result()
83
84 self._current_task = None
85
86 diff --git a/pym/_emerge/CompositeTask.py b/pym/_emerge/CompositeTask.py
87 index 4662f0cf5..1edec4a17 100644
88 --- a/pym/_emerge/CompositeTask.py
89 +++ b/pym/_emerge/CompositeTask.py
90 @@ -69,6 +69,7 @@ class CompositeTask(AsynchronousTask):
91 self._assert_current(task)
92 if task.returncode != os.EX_OK:
93 self.returncode = task.returncode
94 + self.cancelled = task.cancelled
95 self._current_task = None
96 return task.returncode
97
98
99 diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
100 index d9f7f6da7..8d264dd1c 100644
101 --- a/pym/_emerge/EbuildBuild.py
102 +++ b/pym/_emerge/EbuildBuild.py
103 @@ -54,6 +54,10 @@ class EbuildBuild(CompositeTask):
104
105 def _start_with_metadata(self, aux_get_task):
106 self._assert_current(aux_get_task)
107 + if aux_get_task.cancelled:
108 + self._default_final_exit(aux_get_task)
109 + return
110 +
111 pkg = self.pkg
112 settings = self.settings
113 root_config = pkg.root_config
114 @@ -178,6 +182,10 @@ class EbuildBuild(CompositeTask):
115
116 def _start_pre_clean(self, lock_task):
117 self._assert_current(lock_task)
118 + if lock_task.cancelled:
119 + self._default_final_exit(lock_task)
120 + return
121 +
122 lock_task.future.result()
123 # Cleaning needs to happen before fetch, since the build dir
124 # is used for log handling.
125 @@ -235,6 +243,10 @@ class EbuildBuild(CompositeTask):
126
127 def _start_fetch(self, fetcher, already_fetched_task):
128 self._assert_current(already_fetched_task)
129 + if already_fetched_task.cancelled:
130 + self._default_final_exit(already_fetched_task)
131 + return
132 +
133 try:
134 already_fetched = already_fetched_task.future.result()
135 except portage.exception.InvalidDependString as e:
136 @@ -342,6 +354,10 @@ class EbuildBuild(CompositeTask):
137
138 def _unlock_builddir_exit(self, unlock_task, returncode=None):
139 self._assert_current(unlock_task)
140 + if unlock_task.cancelled:
141 + self._default_final_exit(unlock_task)
142 + return
143 +
144 # Normally, async_unlock should not raise an exception here.
145 unlock_task.future.result()
146 if returncode is not None:
147
148 diff --git a/pym/_emerge/EbuildFetcher.py b/pym/_emerge/EbuildFetcher.py
149 index 3b30ebb59..ad5109c28 100644
150 --- a/pym/_emerge/EbuildFetcher.py
151 +++ b/pym/_emerge/EbuildFetcher.py
152 @@ -47,6 +47,10 @@ class EbuildFetcher(CompositeTask):
153
154 def _start_fetch(self, uri_map_task):
155 self._assert_current(uri_map_task)
156 + if uri_map_task.cancelled:
157 + self._default_final_exit(uri_map_task)
158 + return
159 +
160 try:
161 uri_map = uri_map_task.future.result()
162 except portage.exception.InvalidDependString as e:
163 @@ -71,6 +75,10 @@ class EbuildFetcher(CompositeTask):
164
165 def _start_with_metadata(self, aux_get_task):
166 self._assert_current(aux_get_task)
167 + if aux_get_task.cancelled:
168 + self._default_final_exit(aux_get_task)
169 + return
170 +
171 self._fetcher_proc.src_uri, = aux_get_task.future.result()
172 self._start_task(self._fetcher_proc, self._default_final_exit)
173
174 @@ -85,6 +93,10 @@ class _EbuildFetcherProcess(ForkProcess):
175 result = self.scheduler.create_future()
176
177 def uri_map_done(uri_map_future):
178 + if uri_map_future.cancelled():
179 + result.cancel()
180 + return
181 +
182 if uri_map_future.exception() is not None or result.cancelled():
183 if not result.cancelled():
184 result.set_exception(uri_map_future.exception())
185
186 diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
187 index d057dc45e..4104cefa7 100644
188 --- a/pym/_emerge/EbuildPhase.py
189 +++ b/pym/_emerge/EbuildPhase.py
190 @@ -211,6 +211,10 @@ class EbuildPhase(CompositeTask):
191 def _ebuild_exit_unlocked(self, ebuild_process, unlock_task=None):
192 if unlock_task is not None:
193 self._assert_current(unlock_task)
194 + if unlock_task.cancelled:
195 + self._default_final_exit(unlock_task)
196 + return
197 +
198 # Normally, async_unlock should not raise an exception here.
199 unlock_task.future.result()
200
201
202 diff --git a/pym/_emerge/PackageUninstall.py b/pym/_emerge/PackageUninstall.py
203 index 3fe1fb0a6..cb3413056 100644
204 --- a/pym/_emerge/PackageUninstall.py
205 +++ b/pym/_emerge/PackageUninstall.py
206 @@ -61,6 +61,10 @@ class PackageUninstall(CompositeTask):
207
208 def _start_unmerge(self, lock_task):
209 self._assert_current(lock_task)
210 + if lock_task.cancelled:
211 + self._default_final_exit(lock_task)
212 + return
213 +
214 lock_task.future.result()
215 portage.prepare_build_dirs(
216 settings=self.settings, cleanup=True)
217 @@ -112,6 +116,10 @@ class PackageUninstall(CompositeTask):
218
219 def _unlock_builddir_exit(self, unlock_task, returncode=None):
220 self._assert_current(unlock_task)
221 + if unlock_task.cancelled:
222 + self._default_final_exit(unlock_task)
223 + return
224 +
225 # Normally, async_unlock should not raise an exception here.
226 unlock_task.future.result()
227 if returncode is not None:
228
229 diff --git a/pym/portage/_emirrordist/FetchIterator.py b/pym/portage/_emirrordist/FetchIterator.py
230 index 04d4da62b..4ad797502 100644
231 --- a/pym/portage/_emirrordist/FetchIterator.py
232 +++ b/pym/portage/_emirrordist/FetchIterator.py
233 @@ -135,11 +135,21 @@ def _async_fetch_tasks(config, hash_filter, repo_config, digests_future, cpv,
234 if not gather_result.cancelled():
235 list(future.exception() for future in gather_result.result()
236 if not future.cancelled())
237 + else:
238 + result.cancel()
239
240 if result.cancelled():
241 return
242
243 aux_get_result, fetch_map_result = gather_result.result()
244 + if aux_get_result.cancelled() or fetch_map_result.cancelled():
245 + # Cancel result after consuming any exceptions which
246 + # are now irrelevant due to cancellation.
247 + aux_get_result.cancelled() or aux_get_result.exception()
248 + fetch_map_result.cancelled() or fetch_map_result.exception()
249 + result.cancel()
250 + return
251 +
252 try:
253 restrict, = aux_get_result.result()
254 except (PortageKeyError, PortageException) as e: