Merge lp:~jtv/launchpad/cache-pofile-view-permissions into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 11989
Proposed branch: lp:~jtv/launchpad/cache-pofile-view-permissions
Merge into: lp:launchpad
Diff against target: 69 lines (+10/-12)
2 files modified
lib/lp/translations/browser/pofile.py (+8/-8)
lib/lp/translations/browser/translationmessage.py (+2/-4)
To merge this branch: bzr merge lp:~jtv/launchpad/cache-pofile-view-permissions
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+41930@code.launchpad.net

Commit message

[r=adeuring][ui=none][bug=297136] Cache permissions across messages on POFile:+translate pages.

Description of the change

= Bug 297136 =

This should strip a few dozen pointlessly repeated queries off the performance-critical POFile:+translate pages. I came across the omissions while working on something else. The queries don't cost that much time, but we'll often see around a hundred of them on a single request and there's just no good reason for that.

My branch effectively hoists a few very similar checks from the individual message views up into the surrounding POFile page view (if any). The checks all depend on the relationship between the user and the POFile, and global system state. Neither will ever differ between messages on the same translate page.

(There's also a very minor cleanup of list handling at the end).

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

(10:52:35) adeuring: jtv: IN line 37 of the diff, you run "if self.form_is_writeable:" for each loop iteration. I think you can move the "if" outside the loop
(10:53:06) jtv: adeuring: true… it's a cachedproperty, but with this short a loop I guess that makes sense.
(10:53:41) adeuring: jtv: yeah, that's a real micro-optimisation...
(10:53:42) ***jtv looks again
(10:53:59) jtv: Heh, I had missed how completely nonsensical the loop becomes in one of the two cases. :)
(10:54:50) adeuring: ;)
(10:54:57) jtv: And now it becomes clear that this is just one big list comprehension.
(10:55:48) adeuring: jtv: perhaps I had not have yet enogh coffee -- but where did the "alt_current.setPOFile(alt_pofile)" from line 49 go to? Or is it simply unnecessary?
(10:58:15) jtv: adeuring: that's what made me clean this up—alt_current goes into alt_submissions, which is really just [alt_current] + alt_external, so at the end I just have to loop over alt_submissions instead of alt_external.
(10:58:44) adeuring: jtv: ah, thanks! r=me, then.

review: Approve (code)
Revision history for this message
Abel Deuring (adeuring) wrote :

very nice!

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/translations/browser/pofile.py'
2--- lib/lp/translations/browser/pofile.py 2010-11-16 13:10:43 +0000
3+++ lib/lp/translations/browser/pofile.py 2010-11-26 10:03:59 +0000
4@@ -289,12 +289,12 @@
5 def contributors(self):
6 return tuple(self.context.contributors)
7
8- @property
9+ @cachedproperty
10 def user_can_edit(self):
11 """Does the user have full edit rights for this translation?"""
12 return self.context.canEditTranslations(self.user)
13
14- @property
15+ @cachedproperty
16 def user_can_suggest(self):
17 """Is the user allowed to make suggestions here?"""
18 return self.context.canAddSuggestions(self.user)
19@@ -824,11 +824,11 @@
20
21 def _buildTranslationMessageViews(self, for_potmsgsets):
22 """Build translation message views for all potmsgsets given."""
23+ can_edit = self.context.canEditTranslations(self.user)
24 for potmsgset in for_potmsgsets:
25 translationmessage = (
26 potmsgset.getCurrentTranslationMessageOrDummy(self.context))
27 error = self.errors.get(potmsgset)
28- can_edit = self.context.canEditTranslations(self.user)
29
30 view = self._prepareView(
31 CurrentTranslationMessageView, translationmessage,
32@@ -984,11 +984,11 @@
33
34 def _messages_html_id(self):
35 order = []
36- for message in self.translationmessage_views:
37- if (message.form_is_writeable):
38- for dictionary in message.translation_dictionaries:
39- order.append(
40- dictionary['html_id_translation'] + '_new')
41+ if self.form_is_writeable:
42+ for message in self.translationmessage_views:
43+ order += [
44+ dictionary['html_id_translation'] + '_new'
45+ for dictionary in message.translation_dictionaries]
46 return order
47
48 @property
49
50=== modified file 'lib/lp/translations/browser/translationmessage.py'
51--- lib/lp/translations/browser/translationmessage.py 2010-10-28 09:54:48 +0000
52+++ lib/lp/translations/browser/translationmessage.py 2010-11-26 10:03:59 +0000
53@@ -1236,14 +1236,12 @@
54 alt_current = potmsgset.getCurrentTranslationMessage(
55 self.pofile.potemplate, self.sec_lang)
56 if alt_current is not None:
57- alt_current.setPOFile(alt_pofile)
58- if alt_current is not None:
59 alt_submissions.append(alt_current)
60 alt_external = list(
61 potmsgset.getExternallyUsedTranslationMessages(self.sec_lang))
62- for suggestion in alt_external:
63+ alt_submissions.extend(alt_external)
64+ for suggestion in alt_submissions:
65 suggestion.setPOFile(alt_pofile)
66- alt_submissions.extend(alt_external)
67 alt_title = self.sec_lang.englishname
68
69 # To maintain compatibility with the old DB model as much as possible,