Merge lp:~sinzui/launchpad/portlet-package-summary-timeout into lp:launchpad

Proposed by Curtis Hovey on 2010-02-25
Status: Merged
Merged at revision: not available
Proposed branch: lp:~sinzui/launchpad/portlet-package-summary-timeout
Merge into: lp:launchpad
Diff against target: 153 lines (+31/-22)
4 files modified
lib/lp/registry/doc/distroseries.txt (+1/-1)
lib/lp/registry/model/distroseries.py (+13/-3)
lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt (+11/-7)
lib/lp/registry/tests/test_distroseries.py (+6/-11)
To merge this branch: bzr merge lp:~sinzui/launchpad/portlet-package-summary-timeout
Reviewer Review Type Date Requested Status
Paul Hummer (community) code 2010-02-25 Approve on 2010-02-25
Review via email: mp+20147@code.launchpad.net
To post a comment you must log in.
Curtis Hovey (sinzui) wrote :

This is my branch to make getMostRecentlyLinkedPackagings faster.

    lp:~sinzui/launchpad/portlet-package-summary-timeout
    Diff size: 154
    Launchpad bug: https://bugs.launchpad.net/bugs/526583
    Test command: ./bin/test -vv -t reg.*distroseries
    Pre-implementation: Edwin, jtv
    Target release: 10.02

Make getMostRecentlyLinkedPackagings faster
-------------------------------------------

1 in 3 page loads of the /ubuntu/lucid timesout.
getMostRecentlyLinkedPackagings() is expensive call. It needs to be faster, or
we need to consider a cache. We cannot release this portlet if this problem
persists.

Rules
-----

    * Add a filter on bug.heat that will ignore the cold bugs. A filter of
      > 200 reduces the hottest bugs to about from 700 to 200 and is 4 times
      faster on staging. The most viewed pages are unchanged by this filter.
      The query or implementation can be revisited in 10.03 when we get more
      user feedback.
    * bug.hottness was renamed to bug.heat; update the tests to use the same
      term.
    * bug.heat can now be set by admins using setHeat(); remove the SQL
      hacks to set bug heat.
    * Uncomment the distroseries packaging portlet story to verify it
      is how users will discover the needs upstream linking page.

QA
--

    * Visit http://staging.launchpad.net/ubuntu/lucid
    * Verify the page does not timeout.

Lint
----

Linting changed files:
  lib/lp/registry/doc/distroseries.txt
  lib/lp/registry/model/distroseries.py
  lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt
  lib/lp/registry/tests/test_distroseries.py

Test
----

    * lib/lp/registry/doc/distroseries.txt
      * Updated the bug count because the cold bugs are not counted.
    * lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt
      * Added heat to one bug to verify the formatting of a singular bug
        is correct.
      * Updated the story to show that users will get to +needs-packaging
        via the portlet.
    * lib/lp/registry/tests/test_distroseries.py
      * Updated the message count and heat to look like numbers that are
        actually in the database.
      * Removed the sql hack to set bug heat.
      * Renamed hottness to heat.

Implementation
--------------

    * lib/lp/registry/model/distroseries.py
      * Added a filter on bug.heat to ignore the colder bugs.
      * Extracted the filter and weight to variables so that it is easier
        to update the SQL.

Paul Hummer (rockstar) wrote :

<rockstar> sinzui, what specifically is the portlet you're talking about?
<rockstar> sinzui, ?
<sinzui> https://edge.launchpad.net/ubuntu/lucid <-- Upstream packaging
<rockstar> sinzui, ah, okay, thanks.
<rockstar> sinzui, did you cherry pick to staging or were you running raw queries?
<sinzui> rockstar: I ran raw queries comparing the oops query to the modified one
<rockstar> sinzui, okay.
<rockstar> sinzui, this looks good. r=rockstar

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/doc/distroseries.txt'
2--- lib/lp/registry/doc/distroseries.txt 2010-02-19 12:03:35 +0000
3+++ lib/lp/registry/doc/distroseries.txt 2010-02-25 17:55:29 +0000
4@@ -516,7 +516,7 @@
5 alsa-utils 0 0
6 cnews 0 0
7 libstdc++ 0 0
8- linux-source-2.6.15 1 0
9+ linux-source-2.6.15 0 0
10
11
12 The distroseries getPrioritizedlPackagings() method that returns a prioritized
13
14=== modified file 'lib/lp/registry/model/distroseries.py'
15--- lib/lp/registry/model/distroseries.py 2010-02-19 20:24:52 +0000
16+++ lib/lp/registry/model/distroseries.py 2010-02-25 17:55:29 +0000
17@@ -412,6 +412,11 @@
18 @property
19 def _current_sourcepackage_joins_and_conditions(self):
20 """The SQL joins and conditions to prioritize source packages."""
21+ # Bugs and PO messages are heuristically scored. These queries
22+ # can easily timeout so filters and weights are used to create
23+ # an acceptable prioritization of packages that is fast to excecute.
24+ bug_heat_filter = 200
25+ po_message_weight = .5
26 heat_score = ("""
27 LEFT JOIN (
28 SELECT
29@@ -425,18 +430,21 @@
30 BugTask.sourcepackagename is not NULL
31 AND BugTask.distribution = %(distribution)s
32 AND BugTask.status in %(statuses)s
33+ AND Bug.heat > %(bug_heat_filter)s
34 GROUP BY BugTask.sourcepackagename
35 ) bugs
36 ON SourcePackageName.id = bugs.sourcepackagename
37 """ % sqlvalues(
38 distribution=self.distribution,
39- statuses=UNRESOLVED_BUGTASK_STATUSES))
40+ statuses=UNRESOLVED_BUGTASK_STATUSES,
41+ bug_heat_filter=bug_heat_filter))
42 message_score = ("""
43 LEFT JOIN (
44 SELECT
45 POTemplate.sourcepackagename,
46 POTemplate.distroseries,
47- SUM(POTemplate.messagecount) / 2 AS po_messages,
48+ SUM(POTemplate.messagecount) * %(po_message_weight)s
49+ AS po_messages,
50 SUM(POTemplate.messagecount) AS total_messages
51 FROM POTemplate
52 WHERE
53@@ -448,7 +456,9 @@
54 ) messages
55 ON SourcePackageName.id = messages.sourcepackagename
56 AND DistroSeries.id = messages.distroseries
57- """ % sqlvalues(distroseries=self))
58+ """ % sqlvalues(
59+ distroseries=self,
60+ po_message_weight=po_message_weight))
61 joins = ("""
62 SourcePackageName
63 JOIN SourcePackageRelease spr
64
65=== modified file 'lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt'
66--- lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt 2010-02-17 13:16:21 +0000
67+++ lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt 2010-02-25 17:55:29 +0000
68@@ -63,23 +63,27 @@
69 that need upstream packaging links. The list is prioritized so that the
70 packages with the greatest need are listed first.
71
72- >>> # XXX sinzui 2010-01-21 bug=487793: Enable this when the portlet
73- >>> # is added.
74- >>> #anon_browser.open('http://launchpad.dev/ubuntu/hoary')
75- >>> #anon_browser.getLink('Needs upstream links').click()
76- >>> anon_browser.open(
77- ... 'http://launchpad.dev/ubuntu/hoary/+needs-packaging')
78+ >>> # Make a very hot bug to verify the text formatting rule.
79+ >>> from zope.component import getUtility
80+ >>> from lp.bugs.interfaces.bug import IBugSet
81+ >>> login('admin@canonical.com')
82+ >>> bug = getUtility(IBugSet).get(10)
83+ >>> bug.setHeat(300)
84+ >>> logout()
85+
86+ >>> anon_browser.open('http://launchpad.dev/ubuntu/hoary')
87+ >>> anon_browser.getLink('Needs upstream links').click()
88 >>> print anon_browser.title
89 Needs upstream links : ...
90
91 >>> content = find_main_content(anon_browser.contents)
92 >>> print extract_text(find_tag_by_id(content, 'packages'))
93 Source Package Bugs Translations
94+ linux-source-2.6.15 1 bug No strings
95 pmount No bugs 64 strings
96 alsa-utils No bugs No strings
97 cnews No bugs No strings
98 libstdc++ No bugs No strings
99- linux-source-2.6.15 1 bug No strings
100
101 The counts in the listing link to their respect bugs and translations
102 pages.
103
104=== modified file 'lib/lp/registry/tests/test_distroseries.py'
105--- lib/lp/registry/tests/test_distroseries.py 2010-02-19 12:03:35 +0000
106+++ lib/lp/registry/tests/test_distroseries.py 2010-02-25 17:55:29 +0000
107@@ -12,7 +12,6 @@
108 from zope.component import getUtility
109 from zope.security.proxy import removeSecurityProxy
110
111-from canonical.database.sqlbase import cursor
112 from canonical.launchpad.ftests import ANONYMOUS, login
113 from lp.soyuz.interfaces.archive import ArchivePurpose, IArchiveSet
114 from lp.registry.interfaces.distroseries import (
115@@ -210,9 +209,9 @@
116 self.main_component = component_set['main']
117 self.universe_component = component_set['universe']
118 self.makeSeriesPackage('normal')
119- self.makeSeriesPackage('translatable', messages=120)
120- self.makeSeriesPackage('hot', hotness=100)
121- self.makeSeriesPackage('hot-translatable', hotness=80, messages=60)
122+ self.makeSeriesPackage('translatable', messages=800)
123+ self.makeSeriesPackage('hot', heat=500)
124+ self.makeSeriesPackage('hot-translatable', heat=250, messages=1000)
125 self.makeSeriesPackage('main', is_main=True)
126 self.makeSeriesPackage('linked')
127 self.linkPackage('linked')
128@@ -220,7 +219,7 @@
129 login(ANONYMOUS)
130
131 def makeSeriesPackage(self, name,
132- is_main=False, hotness=None, messages=None):
133+ is_main=False, heat=None, messages=None):
134 # Make a published source package.
135 if is_main:
136 component = self.main_component
137@@ -232,14 +231,10 @@
138 component=component)
139 source_package = self.factory.makeSourcePackage(
140 sourcepackagename=sourcepackagename, distroseries=self.series)
141- if hotness is not None:
142+ if heat is not None:
143 bugtask = self.factory.makeBugTask(
144 target=source_package, owner=self.user)
145- # hotness is not exposed in the model yet.
146- # bugtask.bug.hotness = hotness
147- cur = cursor()
148- cur.execute("UPDATE Bug SET heat = %d WHERE id = %d" % (
149- (hotness, bugtask.bug.id)))
150+ bugtask.bug.setHeat(heat)
151 if messages is not None:
152 template = self.factory.makePOTemplate(
153 distroseries=self.series, sourcepackagename=sourcepackagename,