Merge lp:~wgrant/launchpad/bug-750949 into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 12748
Proposed branch: lp:~wgrant/launchpad/bug-750949
Merge into: lp:launchpad
Diff against target: 124 lines (+41/-7)
4 files modified
lib/canonical/launchpad/webapp/publication.py (+2/-0)
lib/lp/bugs/browser/bugattachment.py (+3/-0)
lib/lp/bugs/browser/tests/test_bugtask.py (+28/-3)
lib/lp/bugs/model/bug.py (+8/-4)
To merge this branch: bzr merge lp:~wgrant/launchpad/bug-750949
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Review via email: mp+56295@code.launchpad.net

Commit message

[r=lifeless][bug=750949] Preload attachment LibraryFileContents to eliminate another BugTask:+index scaling issue.

Description of the change

Bug comments display the size of any associated attachments, which requires the LibraryFileContent. This branch expands the LFA preloading to LFCs too, and adds a test.

Ahhh, the test. Browsing to a bug page caused canonical_url(attachment) to die, which I eventually tracked down to BugAttachmentURL depending on a value in ILaunchBag. While one could argue that BugAttachmentURL should be fixed, how it should be fixed is not entirely clear. So, I opted to avoid hours more of future confusion by clearing LaunchBag at the end of each request. It's already cleared at the start, so it won't affect the webapp. Some tests touch LaunchBag inappropriately, but that's mostly to get the current logged in user, not anything from a browser request.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/webapp/publication.py'
2--- lib/canonical/launchpad/webapp/publication.py 2011-03-29 00:11:57 +0000
3+++ lib/canonical/launchpad/webapp/publication.py 2011-04-05 06:57:34 +0000
4@@ -708,6 +708,8 @@
5
6 da.clear_request_started()
7
8+ getUtility(IOpenLaunchBag).clear()
9+
10 # Maintain operational statistics.
11 if getattr(request, '_wants_retry', False):
12 OpStats.stats['retries'] += 1
13
14=== modified file 'lib/lp/bugs/browser/bugattachment.py'
15--- lib/lp/bugs/browser/bugattachment.py 2011-03-28 00:43:40 +0000
16+++ lib/lp/bugs/browser/bugattachment.py 2011-04-05 06:57:34 +0000
17@@ -92,6 +92,9 @@
18 usedfor = IBugAttachmentSet
19
20
21+# Despite declaring compliance with ICanonicalUrlData, the LaunchBag
22+# dependency means this tends towards the "not canonical at all" end of
23+# the canonicalness scale. Beware.
24 class BugAttachmentURL:
25 """Bug URL creation rules."""
26 implements(ICanonicalUrlData)
27
28=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
29--- lib/lp/bugs/browser/tests/test_bugtask.py 2011-03-23 16:28:51 +0000
30+++ lib/lp/bugs/browser/tests/test_bugtask.py 2011-04-05 06:57:34 +0000
31@@ -20,7 +20,10 @@
32 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
33 from canonical.launchpad.webapp import canonical_url
34 from canonical.launchpad.webapp.servers import LaunchpadTestRequest
35-from canonical.testing.layers import DatabaseFunctionalLayer
36+from canonical.testing.layers import (
37+ DatabaseFunctionalLayer,
38+ LaunchpadFunctionalLayer,
39+ )
40 from lp.bugs.browser.bugtask import (
41 BugTaskEditView,
42 BugTasksAndNominationsView,
43@@ -30,11 +33,15 @@
44 from lp.services.propertycache import get_property_cache
45 from lp.soyuz.interfaces.component import IComponentSet
46 from lp.testing import (
47+ celebrity_logged_in,
48 person_logged_in,
49 TestCaseWithFactory,
50 )
51 from lp.testing._webservice import QueryCollector
52-from lp.testing.matchers import HasQueryCount
53+from lp.testing.matchers import (
54+ BrowsesWithQueryLimit,
55+ HasQueryCount,
56+ )
57 from lp.testing.sampledata import (
58 ADMIN_EMAIL,
59 NO_PRIVILEGE_EMAIL,
60@@ -45,7 +52,7 @@
61
62 class TestBugTaskView(TestCaseWithFactory):
63
64- layer = DatabaseFunctionalLayer
65+ layer = LaunchpadFunctionalLayer
66
67 def invalidate_caches(self, obj):
68 store = Store.of(obj)
69@@ -84,6 +91,24 @@
70 LessThan(count_with_no_teams + 3),
71 ))
72
73+ def test_rendered_query_counts_constant_with_attachments(self):
74+ with celebrity_logged_in('admin'):
75+ browses_under_limit = BrowsesWithQueryLimit(
76+ 71, self.factory.makePerson())
77+
78+ # First test with a single attachment.
79+ task = self.factory.makeBugTask()
80+ self.factory.makeBugAttachment(bug=task.bug)
81+ self.assertThat(task, browses_under_limit)
82+
83+ with celebrity_logged_in('admin'):
84+ # And now with 10.
85+ task = self.factory.makeBugTask()
86+ self.factory.makeBugTask(bug=task.bug)
87+ for i in range(10):
88+ self.factory.makeBugAttachment(bug=task.bug)
89+ self.assertThat(task, browses_under_limit)
90+
91 def test_interesting_activity(self):
92 # The interesting_activity property returns a tuple of interesting
93 # `BugActivityItem`s.
94
95=== modified file 'lib/lp/bugs/model/bug.py'
96--- lib/lp/bugs/model/bug.py 2011-04-01 00:47:03 +0000
97+++ lib/lp/bugs/model/bug.py 2011-04-05 06:57:34 +0000
98@@ -87,7 +87,10 @@
99 from canonical.launchpad.components.decoratedresultset import (
100 DecoratedResultSet,
101 )
102-from canonical.launchpad.database.librarian import LibraryFileAlias
103+from canonical.launchpad.database.librarian import (
104+ LibraryFileAlias,
105+ LibraryFileContent,
106+ )
107 from canonical.launchpad.database.message import (
108 Message,
109 MessageChunk,
110@@ -1935,10 +1938,11 @@
111 # See bug 542274 for more details.
112 store = Store.of(self)
113 return store.find(
114- (BugAttachment, LibraryFileAlias),
115+ (BugAttachment, LibraryFileAlias, LibraryFileContent),
116 BugAttachment.bug == self,
117- BugAttachment.libraryfile == LibraryFileAlias.id,
118- LibraryFileAlias.content != None).order_by(BugAttachment.id)
119+ BugAttachment.libraryfileID == LibraryFileAlias.id,
120+ LibraryFileContent.id == LibraryFileAlias.contentID,
121+ ).order_by(BugAttachment.id)
122
123 @property
124 def attachments(self):