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
=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py 2009-07-17 00:26:05 +0000
+++ lib/lp/registry/browser/productseries.py 2009-07-21 16:30:28 +0000
@@ -47,14 +47,13 @@
47from lp.code.interfaces.codeimport import (47from lp.code.interfaces.codeimport import (
48 ICodeImportSet)48 ICodeImportSet)
49from lp.services.worlddata.interfaces.country import ICountry49from lp.services.worlddata.interfaces.country import ICountry
50from lp.bugs.interfaces.bugtask import BugTaskSearchParams, IBugTaskSet50from lp.bugs.interfaces.bugtask import IBugTaskSet
51from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities51from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
52from lp.registry.browser import StatusCount52from lp.registry.browser import StatusCount
53from lp.translations.interfaces.potemplate import IPOTemplateSet53from lp.translations.interfaces.potemplate import IPOTemplateSet
54from lp.translations.interfaces.productserieslanguage import (54from lp.translations.interfaces.productserieslanguage import (
55 IProductSeriesLanguageSet)55 IProductSeriesLanguageSet)
56from lp.services.worlddata.interfaces.language import ILanguageSet56from lp.services.worlddata.interfaces.language import ILanguageSet
57from canonical.launchpad.searchbuilder import any
58from canonical.launchpad.webapp import (57from canonical.launchpad.webapp import (
59 action, ApplicationMenu, canonical_url, custom_widget,58 action, ApplicationMenu, canonical_url, custom_widget,
60 enabled_with_permission, LaunchpadEditFormView,59 enabled_with_permission, LaunchpadEditFormView,
@@ -69,6 +68,7 @@
6968
70from lp.registry.browser import (69from lp.registry.browser import (
71 MilestoneOverlayMixin, RegistryDeleteViewMixin)70 MilestoneOverlayMixin, RegistryDeleteViewMixin)
71from lp.registry.interfaces.distroseries import DistroSeriesStatus
72from lp.registry.interfaces.productseries import IProductSeries72from lp.registry.interfaces.productseries import IProductSeries
73from lp.registry.interfaces.sourcepackagename import (73from lp.registry.interfaces.sourcepackagename import (
74 ISourcePackageNameSet)74 ISourcePackageNameSet)
@@ -417,6 +417,17 @@
417 return (branch is not None and417 return (branch is not None and
418 check_permission('launchpad.View', branch))418 check_permission('launchpad.View', branch))
419419
420 @property
421 def is_obsolete(self):
422 """Return True if the series is OBSOLETE"
423
424 Obsolete series do not need to display as much information of other
425 series. Accessing private bugs is an expensive operation and showing
426 them for obsolete series can be a problem if many series are being
427 displayed.
428 """
429 return self.context.status == DistroSeriesStatus.OBSOLETE
430
420 @cachedproperty431 @cachedproperty
421 def bugtask_status_counts(self):432 def bugtask_status_counts(self):
422 """A list StatusCounts summarising the targeted bugtasks."""433 """A list StatusCounts summarising the targeted bugtasks."""
423434
=== modified file 'lib/lp/registry/browser/tests/productseries-views.txt'
--- lib/lp/registry/browser/tests/productseries-views.txt 2009-07-07 11:24:01 +0000
+++ lib/lp/registry/browser/tests/productseries-views.txt 2009-07-21 16:30:28 +0000
@@ -60,6 +60,22 @@
60 >>> print view.milestone_table_class60 >>> print view.milestone_table_class
61 listing61 listing
6262
63Obsolete series are less interesting that other series. The ProductSeriesView
64has an is_obsolete property that templates can check when choosing the content
65to display.
66
67 >>> from lp.registry.interfaces.distroseries import DistroSeriesStatus
68
69 >>> print series.status
70 Active Development
71 >>> view.is_obsolete
72 False
73
74 >>> series.status = DistroSeriesStatus.OBSOLETE
75 >>> view = create_view(series, '+index')
76 >>> view.is_obsolete
77 True
78
6379
64== Delete ProductSeries ==80== Delete ProductSeries ==
6581
6682
=== modified file 'lib/lp/registry/stories/productseries/xx-productseries-series.txt'
--- lib/lp/registry/stories/productseries/xx-productseries-series.txt 2009-06-29 23:15:46 +0000
+++ lib/lp/registry/stories/productseries/xx-productseries-series.txt 2009-07-21 16:30:28 +0000
@@ -54,12 +54,12 @@
54 >>> print series_1_0['class']54 >>> print series_1_0['class']
55 unhighlighted series55 unhighlighted series
5656
57Any user can see that obsolete series are dimmed.57Any user can see that obsolete series are dimmed. Obsolete series do not
58show bug status counts because it is expensive to retrieve the information.
5859
59 >>> series_xxx = find_tag_by_id(content, 'series-xxx')60 >>> series_xxx = find_tag_by_id(content, 'series-xxx')
60 >>> print extract_text(series_xxx)61 >>> print extract_text(series_xxx)
61 xxx series Obsolete62 xxx series Obsolete
62 Bugs targeted: None
63 Blueprints targeted: None63 Blueprints targeted: None
64 Use true GTK UI.64 Use true GTK UI.
6565
6666
=== modified file 'lib/lp/registry/templates/productseries-status.pt'
--- lib/lp/registry/templates/productseries-status.pt 2009-07-17 17:59:07 +0000
+++ lib/lp/registry/templates/productseries-status.pt 2009-07-21 16:30:28 +0000
@@ -6,12 +6,14 @@
6 tal:define="6 tal:define="
7 series context;7 series context;
8 is_focus context/is_development_focus;8 is_focus context/is_development_focus;
9 bug_count_status view/bugtask_status_counts;
10 spec_count_status view/specification_status_counts;"9 spec_count_status view/specification_status_counts;"
11 >10 >
12 <metal:series use-macro="series/@@+macros/detailed_display">11 <metal:series use-macro="series/@@+macros/detailed_display">
13 <div metal:fill-slot="extra">12 <div metal:fill-slot="extra">
14 <div>13 <div>
14 <tal:not-obsolete
15 condition="not: view/is_obsolete"
16 define="bug_count_status view/bugtask_status_counts;">
15 Bugs targeted:17 Bugs targeted:
16 <tal:statuses repeat="count_status bug_count_status">18 <tal:statuses repeat="count_status bug_count_status">
17 <span tal:attributes="class string:status${count_status/status/name}">19 <span tal:attributes="class string:status${count_status/status/name}">
@@ -24,6 +26,7 @@
24 None26 None
25 </tal:no-statuses>27 </tal:no-statuses>
26 <br />28 <br />
29 </tal:not-obsolete>
27 Blueprints targeted:30 Blueprints targeted:
28 <tal:statuses repeat="count_status spec_count_status">31 <tal:statuses repeat="count_status spec_count_status">
29 <span tal:attributes="class string:specdelivery${count_status/status/name}">32 <span tal:attributes="class string:specdelivery${count_status/status/name}">
3033