commit: 0a5692bd4f4ab4a54daf2ce09112617cbc21c9ad Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sun Apr 22 22:22:20 2018 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Mon Apr 23 18:39:47 2018 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=0a5692bd
EbuildFetcher: add async_already_fetched method (bug 653810) Add an async_already_fetched method to replace the synchronous already_fetched method, and use it to prevent event loop recursion. Bug: https://bugs.gentoo.org/653810 Reviewed-by: Brian Dolbec <dolsen <AT> gentoo.org> pym/_emerge/EbuildBuild.py | 8 +++++++- pym/_emerge/EbuildFetcher.py | 30 ++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py index 8ad8bcae9..9651bd419 100644 --- a/pym/_emerge/EbuildBuild.py +++ b/pym/_emerge/EbuildBuild.py @@ -216,8 +216,14 @@ class EbuildBuild(CompositeTask): logfile=self.settings.get('PORTAGE_LOG_FILE'), pkg=self.pkg, scheduler=self.scheduler) + self._start_task(AsyncTaskFuture( + future=fetcher.async_already_fetched(self.settings)), + functools.partial(self._start_fetch, fetcher)) + + def _start_fetch(self, fetcher, already_fetched_task): + self._assert_current(already_fetched_task) try: - already_fetched = fetcher.already_fetched(self.settings) + already_fetched = already_fetched_task.future.result() except portage.exception.InvalidDependString as e: msg_lines = [] msg = "Fetch failed for '%s' due to invalid SRC_URI: %s" % \ diff --git a/pym/_emerge/EbuildFetcher.py b/pym/_emerge/EbuildFetcher.py index 8f6cc60fe..589eda85d 100644 --- a/pym/_emerge/EbuildFetcher.py +++ b/pym/_emerge/EbuildFetcher.py @@ -28,7 +28,7 @@ class EbuildFetcher(CompositeTask): CompositeTask.__init__(self, **kwargs) self._fetcher_proc = _EbuildFetcherProcess(**kwargs) - def already_fetched(self, settings): + def async_already_fetched(self, settings): """ Returns True if all files already exist locally and have correct digests, otherwise return False. When returning True, appropriate @@ -38,7 +38,7 @@ class EbuildFetcher(CompositeTask): such messages. This will raise InvalidDependString if SRC_URI is invalid. """ - return self._fetcher_proc.already_fetched(settings) + return self._fetcher_proc.async_already_fetched(settings) def _start(self): self._start_task( @@ -68,11 +68,29 @@ class _EbuildFetcherProcess(ForkProcess): __slots__ = ("config_pool", "ebuild_path", "fetchonly", "fetchall", "pkg", "prefetch", "_digests", "_manifest", "_settings", "_uri_map") - def already_fetched(self, settings): - uri_map = self.scheduler.run_until_complete(self._async_uri_map()) - if not uri_map: - return True + def async_already_fetched(self, settings): + result = self.scheduler.create_future() + + def uri_map_done(uri_map_future): + if uri_map_future.exception() is not None or result.cancelled(): + if not result.cancelled(): + result.set_exception(uri_map_future.exception()) + return + + uri_map = uri_map_future.result() + if uri_map: + result.set_result( + self._check_already_fetched(settings, uri_map)) + else: + result.set_result(True) + + uri_map_future = self._async_uri_map() + result.add_done_callback(lambda result: + aux_get_future.cancel() if result.cancelled() else None) + uri_map_future.add_done_callback(uri_map_done) + return result + def _check_already_fetched(self, settings, uri_map): digests = self._get_digests() distdir = settings["DISTDIR"] allow_missing = self._get_manifest().allow_missing