← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/bug-1635126 into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/bug-1635126 into lp:launchpad.

Commit message:
Fix Archive.getPublishedBinaries API call to have a constant query count.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1635126 in Launchpad itself: "Archive.getPublishedBinaries (for ddebs) keeps timing out"
  https://bugs.launchpad.net/launchpad/+bug/1635126

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/bug-1635126/+merge/308915

Fix Archive.getPublishedBinaries API call to have a constant query count.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/bug-1635126 into lp:launchpad.
=== modified file 'lib/lp/soyuz/browser/tests/test_archive_webservice.py'
--- lib/lp/soyuz/browser/tests/test_archive_webservice.py	2015-11-26 15:46:38 +0000
+++ lib/lp/soyuz/browser/tests/test_archive_webservice.py	2016-10-20 12:00:42 +0000
@@ -526,6 +526,23 @@
         publications = ws_archive.getPublishedBinaries(ordered=False)
         self.assertEqual(2, len(publications))
 
+    def test_getPublishedBinaries_query_count(self):
+        # getPublishedBinaries has a query count constant in the number of
+        # packages returned.
+        archive_url = api_url(self.archive)
+
+        def create_bpph():
+            with admin_logged_in():
+                self.factory.makeBinaryPackagePublishingHistory(
+                    archive=self.archive)
+
+        def get_binaries():
+            LaunchpadWebServiceCaller('consumer', '').named_get(
+                archive_url, 'getPublishedBinaries').jsonBody()
+
+        recorder1, recorder2 = record_two_runs(get_binaries, create_bpph, 1)
+        self.assertThat(recorder2, HasQueryCount.byEquality(recorder1))
+
 
 class TestremoveCopyNotification(WebServiceTestCase):
     """Test removeCopyNotification."""

=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py	2016-07-14 18:18:13 +0000
+++ lib/lp/soyuz/interfaces/archive.py	2016-10-20 12:00:42 +0000
@@ -1157,6 +1157,7 @@
                           "for this PPA or None if there is no signing "
                           "key available.")))
 
+    @call_with(eager_load=True)
     @rename_parameters_as(
         name="binary_name", distroarchseries="distro_arch_series")
     @operation_parameters(
@@ -1199,7 +1200,7 @@
                           "publications since their last run."),
             required=False),
         )
-    # Really returns ISourcePackagePublishingHistory, see below for
+    # Really returns IBinaryPackagePublishingHistory, see below for
     # patch to avoid circular import.
     @operation_returns_collection_of(Interface)
     @export_operation_as("getPublishedBinaries")
@@ -1207,7 +1208,8 @@
     def getAllPublishedBinaries(name=None, version=None, status=None,
                                 distroarchseries=None, pocket=None,
                                 exact_match=False, created_since_date=None,
-                                ordered=True, order_by_date=False):
+                                ordered=True, order_by_date=False,
+                                eager_load=False):
         """All `IBinaryPackagePublishingHistory` target to this archive.
 
         :param name: binary name filter (exact match or SQL LIKE controlled

=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py	2016-07-29 06:49:41 +0000
+++ lib/lp/soyuz/model/archive.py	2016-10-20 12:00:42 +0000
@@ -865,7 +865,7 @@
                                 distroarchseries=None, pocket=None,
                                 exact_match=False, created_since_date=None,
                                 ordered=True, order_by_date=False,
-                                include_removed=True):
+                                include_removed=True, eager_load=False):
         """See `IArchive`."""
         clauses, order_by = self._getBinaryPublishingBaseClauses(
             name=name, version=version, status=status, pocket=pocket,
@@ -873,9 +873,23 @@
             created_since_date=created_since_date, ordered=ordered,
             order_by_date=order_by_date, include_removed=include_removed)
 
-        return Store.of(self).find(
+        result = Store.of(self).find(
             BinaryPackagePublishingHistory, *clauses).order_by(*order_by)
 
+        def eager_load_api(bpphs):
+            bprs = load_related(
+                BinaryPackageRelease, bpphs, ['binarypackagereleaseID'])
+            load_related(BinaryPackageName, bprs, ['binarypackagenameID'])
+            bpbs = load_related(BinaryPackageBuild, bprs, ['buildID'])
+            sprs = load_related(
+                SourcePackageRelease, bpbs, ['source_package_release_id'])
+            load_related(SourcePackageName, sprs, ['sourcepackagenameID'])
+            load_related(Component, bpphs, ['componentID'])
+            load_related(Section, bpphs, ['sectionID'])
+        if eager_load:
+            result = DecoratedResultSet(result, pre_iter_hook=eager_load_api)
+        return result
+
     def getPublishedOnDiskBinaries(self, name=None, version=None, status=None,
                                    distroarchseries=None, pocket=None,
                                    exact_match=False):


Follow ups