Merge lp:~gary/launchpad/bug741684 into lp:launchpad
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 12715 | ||||||||
Proposed branch: | lp:~gary/launchpad/bug741684 | ||||||||
Merge into: | lp:launchpad | ||||||||
Diff against target: |
450 lines (+183/-67) 6 files modified
lib/lp/bugs/interfaces/bugnotification.py (+3/-3) lib/lp/bugs/model/bug.py (+1/-1) lib/lp/bugs/model/bugnotification.py (+73/-34) lib/lp/bugs/scripts/bugnotification.py (+42/-14) lib/lp/bugs/scripts/tests/test_bugnotification.py (+29/-12) lib/lp/bugs/tests/test_bugnotification.py (+35/-3) |
||||||||
To merge this branch: | bzr merge lp:~gary/launchpad/bug741684 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
j.c.sackett (community) | Approve | ||
Review via email: mp+55656@code.launchpad.net |
Description of the change
This branch makes the SQL optimizations I could find for the bug notification script, with one or two exceptions. The first exception is that I felt we could do better with how we are finding the transitive emails for teams. I make that change in another branch, lp:~gary/launchpad/bug741684-2. The other possible exception is that Robert and Stuart seem to disagree on what kind of Storm cache we have in place. In order for these optimizations to be most effective, we may need to prevent Storm cache exhaustion in an additional subsequent change of some sort.
Now I'll describe what actually *is* in this branch.
This branch focuses on two changes to the asynchronous sending of bug notifications, both of which were deployed at the last downtime deployment.
[Feature 1: quickly undone actions should not send email notifications]
The first was to fix bug 164196: quickly undone actions should not send email notifications. In order to determine if an action is undone, the new code connected our notification records with our log records for a given change. For each collection of notifications, each notification's activity was consulted to determine what was changed, and if the end state was the same as the beginning state. This change meant that the script now looks at BugActivity records, and it did not before.
[Feature 2: emails can include notes on what structural subscription filter(s) caused the email to be sent to a recipient, to aid in organizing and highlighting email]
I initially thought that this was the primary change in how we sent our emails. However, perhaps the bigger one from the perspective of database usage was that we looked for structural subscription filters for every notification to see if we need to tell the recipient about what filter caused them to receive the mail. This caused significant database churn in a much tighter loop.
I divide the changes below into sections that first list the file or files that changed, and then discuss the changes.
= Get filters for multiple bug notifications at once =
* lib/lp/
* lib/lp/
* lib/lp/
* lib/lp/
Rather than getting the filters for a particular bug notification, the code now gets the filters for a set of bug notifications when possible. This reduces the number of queries within the tightest loop.
= Cache Bug.initial_message =
* The code was getting every bug's initial_message twice, and each time was firing a SQL query. I tried cacheing it. If that causes problems, I'll get the value once in the bugnotification script code instead.
= Pre-load database values for BugNotification
* lib/lp/
This change loads as much as possible of what we will need later into the Storm cache. This is therefore the change that may need tweaks of our Storm cache, as discussed above. It is also a revised version of the code that was attempted earlier as a cowboy, to no great improvement. This version may be better.
We load the direct (and smaller) dependencies immediately, simultaneously as we load the notifications; then, after we have gotten the notifications and determined what will be used, we preload the bugs and the people (using the IPersonSet method that also loads the email information that we will need later).
= Only get the filters for the "top level" recipients, not for the transitively exploded full recipient list =
* lib/lp/
I am hopeful that this will be the most important optimization. It completely eliminates the tightest loop whenever a team that does not have a preferred email is set. It then also takes advantage of the change described above in the section titled "Get filters for multiple bug notifications at once." This change should be transparent, while generating a lot less work in certain cases.
I investigated many other potential optimizations, but these were the ones I found that kept the desired behavior and actually reduced the SQL when I attempted them.
Thank you for the review.
Gary--
This is a clear improvement, thanks.
If we continue to see issues with scripts/ bugnotification .py, I think there is still a chance that there's some churn in the for loop that repeatedly calls get_filter_ descriptions (and through it, your improved getFiltersByRec ipient) , but you've done a lot to make that section cleaner.