Merge lp:~sinzui/launchpad/series-performance into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~sinzui/launchpad/series-performance
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~sinzui/launchpad/series-performance
Reviewer Review Type Date Requested Status
Francis J. Lacoste (community) release-critical Approve
Brad Crittenden (community) Approve
Review via email: mp+9100@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

This is my branch to address +series timeouts.

    lp:~sinzui/launchpad/series-performance
    Diff size: 120
    Launchpad bug: https://bugs.launchpad.net/bugs/396135
    Test command: ./bin/test -vvt "productseries-views|xx-productseries-series"
    Pre-implementation: Edwin
    Target release: 2.2.7

= +series timeouts =

The longest step is rendering the +series page is checking the privacy
of bugs. The +series page presents a count of all bug status for a series.
Since bug privacy is an expensive feature to re-implement, the +series page
must be more selective about which bugs to count.

Obsolete series are less interesting that other series. They do not need
bug status counts. In the bzr/+series example, there are 29 obsolete series
and 7 series that are other statuses. There are about 200 privacy checks
that can be avoided, as well as SQL calls to get that information.

== Rules ==

Add a condition to the productseries-status.pt template to display the bug
status only when the series is not obsolete

== QA ==

    * Visit https://staging.launchpad.net/bzr/+series
    * Verify that no obsolete series has a "Bugs targeted:" line
    * Load the page repeatedly to verify that the page does no timeout.

== Lint ==

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/registry/browser/productseries.py
  lib/lp/registry/browser/tests/productseries-views.txt
  lib/lp/registry/stories/productseries/xx-productseries-series.txt
  lib/lp/registry/templates/productseries-status.pt

== Test ==

    * lib/lp/registry/browser/tests/productseries-views.txt
      * Added a test to verify that the view provides an is_obsolete
        property.
    * lib/lp/registry/stories/productseries/xx-productseries-series.txt
      * Revised a test to show that obsolete series do not have a
        "Bugs targeted:" line.

== Implementation ==

    * lib/lp/registry/browser/productseries.py
      * Added the is_obsolete property for the template.
    * lib/lp/registry/templates/productseries-status.pt
      * Use the is_obsolete to avoid rendering the "Bugs targeted:" section.

Revision history for this message
Brad Crittenden (bac) wrote :

This fix looks great Curtis.

Two minor fixes:

36: typo: as other

106: indent the code surrounded by your new tag

review: Approve
Revision history for this message
Francis J. Lacoste (flacoste) :
review: Approve (release-critical)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/productseries.py'
2--- lib/lp/registry/browser/productseries.py 2009-07-17 00:26:05 +0000
3+++ lib/lp/registry/browser/productseries.py 2009-07-21 16:30:28 +0000
4@@ -47,14 +47,13 @@
5 from lp.code.interfaces.codeimport import (
6 ICodeImportSet)
7 from lp.services.worlddata.interfaces.country import ICountry
8-from lp.bugs.interfaces.bugtask import BugTaskSearchParams, IBugTaskSet
9+from lp.bugs.interfaces.bugtask import IBugTaskSet
10 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
11 from lp.registry.browser import StatusCount
12 from lp.translations.interfaces.potemplate import IPOTemplateSet
13 from lp.translations.interfaces.productserieslanguage import (
14 IProductSeriesLanguageSet)
15 from lp.services.worlddata.interfaces.language import ILanguageSet
16-from canonical.launchpad.searchbuilder import any
17 from canonical.launchpad.webapp import (
18 action, ApplicationMenu, canonical_url, custom_widget,
19 enabled_with_permission, LaunchpadEditFormView,
20@@ -69,6 +68,7 @@
21
22 from lp.registry.browser import (
23 MilestoneOverlayMixin, RegistryDeleteViewMixin)
24+from lp.registry.interfaces.distroseries import DistroSeriesStatus
25 from lp.registry.interfaces.productseries import IProductSeries
26 from lp.registry.interfaces.sourcepackagename import (
27 ISourcePackageNameSet)
28@@ -417,6 +417,17 @@
29 return (branch is not None and
30 check_permission('launchpad.View', branch))
31
32+ @property
33+ def is_obsolete(self):
34+ """Return True if the series is OBSOLETE"
35+
36+ Obsolete series do not need to display as much information of other
37+ series. Accessing private bugs is an expensive operation and showing
38+ them for obsolete series can be a problem if many series are being
39+ displayed.
40+ """
41+ return self.context.status == DistroSeriesStatus.OBSOLETE
42+
43 @cachedproperty
44 def bugtask_status_counts(self):
45 """A list StatusCounts summarising the targeted bugtasks."""
46
47=== modified file 'lib/lp/registry/browser/tests/productseries-views.txt'
48--- lib/lp/registry/browser/tests/productseries-views.txt 2009-07-07 11:24:01 +0000
49+++ lib/lp/registry/browser/tests/productseries-views.txt 2009-07-21 16:30:28 +0000
50@@ -60,6 +60,22 @@
51 >>> print view.milestone_table_class
52 listing
53
54+Obsolete series are less interesting that other series. The ProductSeriesView
55+has an is_obsolete property that templates can check when choosing the content
56+to display.
57+
58+ >>> from lp.registry.interfaces.distroseries import DistroSeriesStatus
59+
60+ >>> print series.status
61+ Active Development
62+ >>> view.is_obsolete
63+ False
64+
65+ >>> series.status = DistroSeriesStatus.OBSOLETE
66+ >>> view = create_view(series, '+index')
67+ >>> view.is_obsolete
68+ True
69+
70
71 == Delete ProductSeries ==
72
73
74=== modified file 'lib/lp/registry/stories/productseries/xx-productseries-series.txt'
75--- lib/lp/registry/stories/productseries/xx-productseries-series.txt 2009-06-29 23:15:46 +0000
76+++ lib/lp/registry/stories/productseries/xx-productseries-series.txt 2009-07-21 16:30:28 +0000
77@@ -54,12 +54,12 @@
78 >>> print series_1_0['class']
79 unhighlighted series
80
81-Any user can see that obsolete series are dimmed.
82+Any user can see that obsolete series are dimmed. Obsolete series do not
83+show bug status counts because it is expensive to retrieve the information.
84
85 >>> series_xxx = find_tag_by_id(content, 'series-xxx')
86 >>> print extract_text(series_xxx)
87 xxx series Obsolete
88- Bugs targeted: None
89 Blueprints targeted: None
90 Use true GTK UI.
91
92
93=== modified file 'lib/lp/registry/templates/productseries-status.pt'
94--- lib/lp/registry/templates/productseries-status.pt 2009-07-17 17:59:07 +0000
95+++ lib/lp/registry/templates/productseries-status.pt 2009-07-21 16:30:28 +0000
96@@ -6,12 +6,14 @@
97 tal:define="
98 series context;
99 is_focus context/is_development_focus;
100- bug_count_status view/bugtask_status_counts;
101 spec_count_status view/specification_status_counts;"
102 >
103 <metal:series use-macro="series/@@+macros/detailed_display">
104 <div metal:fill-slot="extra">
105 <div>
106+ <tal:not-obsolete
107+ condition="not: view/is_obsolete"
108+ define="bug_count_status view/bugtask_status_counts;">
109 Bugs targeted:
110 <tal:statuses repeat="count_status bug_count_status">
111 <span tal:attributes="class string:status${count_status/status/name}">
112@@ -24,6 +26,7 @@
113 None
114 </tal:no-statuses>
115 <br />
116+ </tal:not-obsolete>
117 Blueprints targeted:
118 <tal:statuses repeat="count_status spec_count_status">
119 <span tal:attributes="class string:specdelivery${count_status/status/name}">
120