[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gentoo-portage-dev
Subject:    [gentoo-portage-dev] [PATCH 1/5] portdbapi: add async_fetch_map method (bug 653810)
From:       Zac Medico <zmedico () gentoo ! org>
Date:       2018-04-22 22:30:10
Message-ID: 20180422223014.24341-2-zmedico () gentoo ! org
[Download RAW message or body]

Add a portdbapi.async_fetch_map method which is identical to the
existing portdbapi.getFetchMap method, but returns a future. This
will be used by EbuildFetcher in order to avoid event loop recursion.

Bug: https://bugs.gentoo.org/653810
---
 pym/portage/dbapi/porttree.py | 75 +++++++++++++++++++++++++++++++++----------
 1 file changed, 58 insertions(+), 17 deletions(-)

diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index 951e5760a..3cd929963 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -728,25 +728,66 @@ class portdbapi(dbapi):
 			URIs.
 		@rtype: dict
 		"""
+		loop = self._event_loop
+		return loop.run_until_complete(
+			self.async_fetch_map(mypkg, useflags=useflags,
+				mytree=mytree, loop=loop))
 
-		try:
-			eapi, myuris = self.aux_get(mypkg,
-				["EAPI", "SRC_URI"], mytree=mytree)
-		except KeyError:
-			# Convert this to an InvalidDependString exception since callers
-			# already handle it.
-			raise portage.exception.InvalidDependString(
-				"getFetchMap(): aux_get() error reading "+mypkg+"; aborting.")
+	def async_fetch_map(self, mypkg, useflags=None, mytree=None, loop=None):
+		"""
+		Asynchronous form of getFetchMap.
 
-		if not eapi_is_supported(eapi):
-			# Convert this to an InvalidDependString exception
-			# since callers already handle it.
-			raise portage.exception.InvalidDependString(
-				"getFetchMap(): '%s' has unsupported EAPI: '%s'" % \
-				(mypkg, eapi))
-
-		return _parse_uri_map(mypkg, {'EAPI':eapi,'SRC_URI':myuris},
-			use=useflags)
+		@param mypkg: cpv for an ebuild
+		@type mypkg: String
+		@param useflags: a collection of enabled USE flags, for evaluation of
+			conditionals
+		@type useflags: set, or None to enable all conditionals
+		@param mytree: The canonical path of the tree in which the ebuild
+			is located, or None for automatic lookup
+		@type mypkg: String
+		@param loop: event loop (defaults to global event loop)
+		@type loop: EventLoop
+		@return: A future that results in a dict which maps each file name to
+			a set of alternative URIs.
+		@rtype: asyncio.Future (or compatible)
+		"""
+		loop = loop or global_event_loop()
+		loop = getattr(loop, '_asyncio_wrapper', loop)
+		result = loop.create_future()
+
+		def aux_get_done(aux_get_future):
+			if result.cancelled():
+				return
+			if aux_get_future.exception() is not None:
+				if isinstance(future.exception(), PortageKeyError):
+					# Convert this to an InvalidDependString exception since
+					# callers already handle it.
+					result.set_exception(portage.exception.InvalidDependString(
+						"getFetchMap(): aux_get() error reading "
+						+ mypkg + "; aborting."))
+				else:
+					result.set_exception(future.exception())
+				return
+
+			eapi, myuris = aux_get_future.result()
+
+			if not eapi_is_supported(eapi):
+				# Convert this to an InvalidDependString exception
+				# since callers already handle it.
+				result.set_exception(portage.exception.InvalidDependString(
+					"getFetchMap(): '%s' has unsupported EAPI: '%s'" % \
+					(mypkg, eapi)))
+				return
+
+			result.set_result(_parse_uri_map(mypkg,
+				{'EAPI':eapi,'SRC_URI':myuris}, use=useflags))
+
+		aux_get_future = self.async_aux_get(
+			mypkg, ["EAPI", "SRC_URI"], mytree=mytree)
+		result.add_done_callback(lambda result:
+			aux_get_future.cancel() if result.cancelled() else None)
+		aux_get_future.add_done_callback(aux_get_done)
+		return result
 
 	def getfetchsizes(self, mypkg, useflags=None, debug=0, myrepo=None):
 		# returns a filename:size dictionnary of remaining downloads
-- 
2.13.6


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic