launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #05513
[Merge] lp:~rvb/launchpad/builders-timeout-bug-887078-eager-load2 into lp:launchpad
Raphaël Badin has proposed merging lp:~rvb/launchpad/builders-timeout-bug-887078-eager-load2 into lp:launchpad with lp:~rvb/launchpad/builders-timeout-bug-887078-eager-load-cachedproperty as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #887078 in Launchpad itself: "Builder:+history timeout"
https://bugs.launchpad.net/launchpad/+bug/887078
For more details, see:
https://code.launchpad.net/~rvb/launchpad/builders-timeout-bug-887078-eager-load2/+merge/82200
This branch is a followup on ~rvb/launchpad/builders-timeout-bug-887078-eager-load-cachedproperty.
It eager loads the objects related to a translation template build to avoid issuing one query per translation template build displayed on builder:+history.
= Tests =
./bin/test -vvc test_builder_views test_build_history_queries_count_translation_template_builds
= Q/A =
None.
--
https://code.launchpad.net/~rvb/launchpad/builders-timeout-bug-887078-eager-load2/+merge/82200
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rvb/launchpad/builders-timeout-bug-887078-eager-load2 into lp:launchpad.
=== modified file 'lib/lp/soyuz/browser/tests/test_builder_views.py'
--- lib/lp/soyuz/browser/tests/test_builder_views.py 2011-11-14 17:38:34 +0000
+++ lib/lp/soyuz/browser/tests/test_builder_views.py 2011-11-14 17:38:38 +0000
@@ -5,12 +5,15 @@
from storm.locals import Store
from testtools.matchers import Equals
+from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
from canonical.database.sqlbase import flush_database_caches
from canonical.launchpad.ftests import login
from canonical.launchpad.webapp.servers import LaunchpadTestRequest
from canonical.testing.layers import LaunchpadFunctionalLayer
+from lp.buildmaster.enums import BuildFarmJobType
+from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
from lp.soyuz.browser.builder import BuilderEditView
from lp.testing import (
StormStatementRecorder,
@@ -20,6 +23,9 @@
from lp.testing.matchers import HasQueryCount
from lp.testing.sampledata import ADMIN_EMAIL
from lp.testing.views import create_initialized_view
+from lp.translations.interfaces.translationtemplatesbuild import (
+ ITranslationTemplatesBuildSource,
+ )
class TestBuilderEditView(TestCaseWithFactory):
@@ -69,6 +75,16 @@
super(TestBuilderHistoryView, self).setUp()
self.builder = self.factory.makeBuilder()
+ def createTranslationTemplateBuildWithBuilder(self):
+ build_farm_job_source = getUtility(IBuildFarmJobSource)
+ build_farm_job = build_farm_job_source.new(
+ BuildFarmJobType.TRANSLATIONTEMPLATESBUILD)
+ source = getUtility(ITranslationTemplatesBuildSource)
+ branch = self.factory.makeBranch()
+ build = source.create(build_farm_job, branch)
+ removeSecurityProxy(build).builder = self.builder
+ return build
+
def createRecipeBuildWithBuilder(self):
build = self.factory.makeSourcePackageRecipeBuild()
Store.of(build).flush()
@@ -127,3 +143,14 @@
self.createBinaryPackageBuild)
self.assertThat(recorder2, HasQueryCount(Equals(recorder1.count)))
+
+ def test_build_history_queries_count_translation_template_builds(self):
+ # Rendering to builder's history issues a constant number of queries
+ # when translation template builds are displayed.
+ def call_history_render():
+ create_initialized_view(self.builder, '+history').render()
+ recorder1, recorder2 = self._record_queries_count(
+ call_history_render,
+ self.createTranslationTemplateBuildWithBuilder)
+
+ self.assertThat(recorder2, HasQueryCount(Equals(recorder1.count)))
=== modified file 'lib/lp/translations/model/translationtemplatesbuild.py'
--- lib/lp/translations/model/translationtemplatesbuild.py 2011-11-09 11:36:44 +0000
+++ lib/lp/translations/model/translationtemplatesbuild.py 2011-11-14 17:38:38 +0000
@@ -18,12 +18,19 @@
implements,
)
+from canonical.launchpad.components.decoratedresultset import (
+ DecoratedResultSet,
+ )
from canonical.launchpad.interfaces.lpstorm import IStore
from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
+from lp.code.model.branch import Branch
+from lp.code.model.branchcollection import GenericBranchCollection
from lp.code.model.branchjob import (
BranchJob,
BranchJobType,
)
+from lp.registry.model.product import Product
+from lp.services.database.bulk import load_related
from lp.translations.interfaces.translationtemplatesbuild import (
ITranslationTemplatesBuild,
ITranslationTemplatesBuildSource,
@@ -111,10 +118,20 @@
buildfarmjob_ids = [buildfarmjob.id for buildfarmjob in buildfarmjobs]
"""See `ITranslationTemplatesBuildSource`."""
store = cls._getStore(store)
- return store.find(
+
+ def eager_load(rows):
+ branches = load_related(
+ Branch, rows, ['branch_id'])
+ load_related(
+ Product, branches, ['productID'])
+ branch_collection = GenericBranchCollection()
+ branch_collection._preloadDataForBranches(branches)
+
+ resultset = store.find(
TranslationTemplatesBuild,
TranslationTemplatesBuild.build_farm_job_id.is_in(
buildfarmjob_ids))
+ return DecoratedResultSet(resultset, pre_iter_hook=eager_load)
@classmethod
def findByBranch(cls, branch, store=None):