Merge lp:~wallyworld/launchpad/fast-related-software-feature-flag into lp:launchpad

Proposed by Ian Booth
Status: Merged
Approved by: Ian Booth
Approved revision: no longer in the source branch.
Merged at revision: 16247
Proposed branch: lp:~wallyworld/launchpad/fast-related-software-feature-flag
Merge into: lp:launchpad
Diff against target: 175 lines (+116/-0)
3 files modified
lib/lp/registry/browser/tests/test_person.py (+10/-0)
lib/lp/registry/model/person.py (+99/-0)
lib/lp/services/features/flags.py (+7/-0)
To merge this branch: bzr merge lp:~wallyworld/launchpad/fast-related-software-feature-flag
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Approve
Review via email: mp+133411@code.launchpad.net

Commit message

Add a feature flag so that the related software pages can load using the old queries until the reporting table is populated via the garbo job.

Description of the change

== Implementation ==

Add a feature flag so that the related software pages can load using the old queries until the reporting table is populated via the garbo job. The code is copied from an earlier revision.

The code will all be deleted again soon when the feature flag is removed.

== Tests ==

The relevant tests will now use the old queries.
Add a test just to sanity check the feature flag works and the test then uses the new queries.

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/tests/test_person.py'
2--- lib/lp/registry/browser/tests/test_person.py 2012-11-07 12:38:19 +0000
3+++ lib/lp/registry/browser/tests/test_person.py 2012-11-08 06:08:21 +0000
4@@ -39,6 +39,7 @@
5 from lp.registry.model.milestone import milestone_sort_key
6 from lp.scripts.garbo import PopulateLatestPersonSourcepackageReleaseCache
7 from lp.services.config import config
8+from lp.services.features.testing import FeatureFixture
9 from lp.services.identity.interfaces.account import AccountStatus
10 from lp.services.identity.interfaces.emailaddress import IEmailAddressSet
11 from lp.services.log.logger import FakeLogger
12@@ -912,6 +913,15 @@
13 self.assertEqual(self.view.max_results_to_display, count)
14
15
16+class TestFastPersonRelatedPackagesView(TestPersonRelatedPackagesView):
17+ # Re-run TestPersonRelatedPackagesView with feature flag on.
18+
19+ def setUp(self):
20+ super(TestFastPersonRelatedPackagesView, self).setUp()
21+ self.useFixture(FeatureFixture({
22+ 'registry.fast_related_software.enabled': 'true'}))
23+
24+
25 class TestPersonMaintainedPackagesView(TestCaseWithFactory):
26 """Test the maintained packages view."""
27
28
29=== modified file 'lib/lp/registry/model/person.py'
30--- lib/lp/registry/model/person.py 2012-11-07 12:38:19 +0000
31+++ lib/lp/registry/model/person.py 2012-11-08 06:08:21 +0000
32@@ -264,6 +264,7 @@
33 SQLBase,
34 sqlvalues,
35 )
36+from lp.services.features import getFeatureFlag
37 from lp.services.helpers import (
38 ensure_unicode,
39 shortlist,
40@@ -2871,6 +2872,9 @@
41 """Are there sourcepackagereleases (SPRs) related to this person.
42 See `_releasesQueryFilter` for details on the criteria used.
43 """
44+ if not getFeatureFlag('registry.fast_related_software.enabled'):
45+ return self._legacy_hasReleasesQuery(uploader_only, ppa_only)
46+
47 clauses = self._releasesQueryFilter(uploader_only, ppa_only)
48 rs = Store.of(self).using(LatestPersonSourcepackageReleaseCache).find(
49 LatestPersonSourcepackageReleaseCache.publication_id, *clauses)
50@@ -2879,6 +2883,10 @@
51 def _latestReleasesQuery(self, uploader_only=False, ppa_only=False):
52 """Return the sourcepackagereleases records related to this person.
53 See `_releasesQueryFilter` for details on the criteria used."""
54+
55+ if not getFeatureFlag('registry.fast_related_software.enabled'):
56+ return self._legacy_latestReleasesQuery(uploader_only, ppa_only)
57+
58 clauses = self._releasesQueryFilter(uploader_only, ppa_only)
59 rs = Store.of(self).find(
60 LatestPersonSourcepackageReleaseCache, *clauses).order_by(
61@@ -2896,6 +2904,97 @@
62
63 return DecoratedResultSet(rs, pre_iter_hook=load_related_objects)
64
65+
66+ def _legacy_releasesQueryFilter(self, uploader_only=False, ppa_only=False):
67+ """Return the filter used to find sourcepackagereleases (SPRs)
68+ related to this person.
69+
70+ :param uploader_only: controls if we are interested in SPRs where
71+ the person in question is only the uploader (creator) and not the
72+ maintainer (debian-syncs) if the `ppa_only` parameter is also
73+ False, or, if the flag is False, it returns all SPR maintained
74+ by this person.
75+
76+ :param ppa_only: controls if we are interested only in source
77+ package releases targeted to any PPAs or, if False, sources
78+ targeted to primary archives.
79+
80+ Active 'ppa_only' flag is usually associated with active
81+ 'uploader_only' because there shouldn't be any sense of maintainership
82+ for packages uploaded to PPAs by someone else than the user himself.
83+ """
84+ clauses = [SourcePackageRelease.upload_archive == Archive.id]
85+
86+ if uploader_only:
87+ clauses.append(SourcePackageRelease.creator == self)
88+
89+ if ppa_only:
90+ # Source maintainer is irrelevant for PPA uploads.
91+ pass
92+ elif uploader_only:
93+ clauses.append(SourcePackageRelease.maintainer != self)
94+ else:
95+ clauses.append(SourcePackageRelease.maintainer == self)
96+
97+ if ppa_only:
98+ clauses.append(Archive.purpose == ArchivePurpose.PPA)
99+ else:
100+ clauses.append(Archive.purpose != ArchivePurpose.PPA)
101+
102+ return clauses
103+
104+ def _legacy_hasReleasesQuery(self, uploader_only=False, ppa_only=False):
105+ """Are there sourcepackagereleases (SPRs) related to this person.
106+ See `_legacy_releasesQueryFilter` for details on the criteria used.
107+ """
108+ clauses = self._legacy_releasesQueryFilter(uploader_only, ppa_only)
109+ spph = ClassAlias(SourcePackagePublishingHistory, "spph")
110+ tables = (
111+ SourcePackageRelease,
112+ Join(
113+ spph, spph.sourcepackagereleaseID == SourcePackageRelease.id),
114+ Join(Archive, Archive.id == spph.archiveID))
115+ rs = Store.of(self).using(*tables).find(
116+ SourcePackageRelease.id, clauses)
117+ return not rs.is_empty()
118+
119+ def _legacy_latestReleasesQuery(self, uploader_only=False, ppa_only=False):
120+ """Return the sourcepackagereleases (SPRs) related to this person.
121+ See `_legacy_releasesQueryFilter` for details on the criteria used."""
122+ clauses = self._legacy_releasesQueryFilter(uploader_only, ppa_only)
123+ spph = ClassAlias(SourcePackagePublishingHistory, "spph")
124+ rs = Store.of(self).find(
125+ SourcePackageRelease,
126+ SourcePackageRelease.id.is_in(
127+ Select(
128+ SourcePackageRelease.id,
129+ tables=[
130+ SourcePackageRelease,
131+ Join(
132+ spph,
133+ spph.sourcepackagereleaseID ==
134+ SourcePackageRelease.id),
135+ Join(Archive, Archive.id == spph.archiveID)],
136+ where=And(*clauses),
137+ order_by=[SourcePackageRelease.upload_distroseriesID,
138+ SourcePackageRelease.sourcepackagenameID,
139+ SourcePackageRelease.upload_archiveID,
140+ Desc(SourcePackageRelease.dateuploaded)],
141+ distinct=(
142+ SourcePackageRelease.upload_distroseriesID,
143+ SourcePackageRelease.sourcepackagenameID,
144+ SourcePackageRelease.upload_archiveID)))
145+ ).order_by(
146+ Desc(SourcePackageRelease.dateuploaded), SourcePackageRelease.id)
147+
148+ def load_related_objects(rows):
149+ list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
150+ set(map(attrgetter("maintainerID"), rows))))
151+ bulk.load_related(SourcePackageName, rows, ['sourcepackagenameID'])
152+ bulk.load_related(Archive, rows, ['upload_archiveID'])
153+
154+ return DecoratedResultSet(rs, pre_iter_hook=load_related_objects)
155+
156 def hasSynchronisedPublishings(self):
157 """See `IPerson`."""
158 spph = ClassAlias(SourcePackagePublishingHistory, "spph")
159
160=== modified file 'lib/lp/services/features/flags.py'
161--- lib/lp/services/features/flags.py 2012-10-29 16:52:31 +0000
162+++ lib/lp/services/features/flags.py 2012-11-08 06:08:21 +0000
163@@ -244,6 +244,13 @@
164 'Traversal to private projects requires special access.',
165 'Override traveral checks.',
166 'https://dev.launchpad.net/LEP/PrivateProjects'),
167+ ('registry.fast_related_software.enabled',
168+ 'boolean',
169+ ('If true, use the new reporting cache to load a person\'s related '
170+ 'software information.'),
171+ '',
172+ '',
173+ ''),
174
175 ])
176