Merge lp:~julian-edwards/launchpad/builder-history-timeout-bug-631206 into lp:launchpad

Proposed by Julian Edwards
Status: Merged
Approved by: Julian Edwards
Approved revision: no longer in the source branch.
Merged at revision: 12375
Proposed branch: lp:~julian-edwards/launchpad/builder-history-timeout-bug-631206
Merge into: lp:launchpad
Diff against target: 98 lines (+50/-13)
1 file modified
lib/lp/buildmaster/model/buildfarmjob.py (+50/-13)
To merge this branch: bzr merge lp:~julian-edwards/launchpad/builder-history-timeout-bug-631206
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+49374@code.launchpad.net

Commit message

[r=adeuring][bug=631206] Make Builder:+history load in 2 seconds instead of timing out.

Description of the change

This change optimises the query that is in BuildFarmJobSet.getBuildsForBuilder(). See the bug for more commentary that I won't repeat here. Suffice to say that the page now renders inside 2 seconds instead of timing out fairly consistently for some builders/users combos.

bin/test -cvvt test_getBuildsForBuilder

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

nice work!

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
--- lib/lp/buildmaster/model/buildfarmjob.py 2010-10-04 21:44:32 +0000
+++ lib/lp/buildmaster/model/buildfarmjob.py 2011-02-14 10:20:55 +0000
@@ -15,10 +15,12 @@
15from lazr.delegates import delegates15from lazr.delegates import delegates
16import pytz16import pytz
17from storm.expr import (17from storm.expr import (
18 Coalesce,18 And,
19 Desc,19 Desc,
20 LeftJoin,20 LeftJoin,
21 Or,21 Or,
22 Select,
23 Union,
22 )24 )
23from storm.locals import (25from storm.locals import (
24 Bool,26 Bool,
@@ -400,19 +402,55 @@
400 # Currently only package builds can be private (via their402 # Currently only package builds can be private (via their
401 # related archive), but not all build farm jobs will have a403 # related archive), but not all build farm jobs will have a
402 # related package build - hence the left join.404 # related package build - hence the left join.
403 origin = [BuildFarmJob]405 origin = [
404 left_join_archive = [406 BuildFarmJob,
405 LeftJoin(407 LeftJoin(
406 PackageBuild,408 PackageBuild,
407 PackageBuild.build_farm_job == BuildFarmJob.id),409 PackageBuild.build_farm_job == BuildFarmJob.id),
408 LeftJoin(
409 Archive, PackageBuild.archive == Archive.id),
410 ]410 ]
411411
412 # STORM syntax has totally obfuscated this query and wasted
413 # THREE hours of my time converting perfectly good SQL syntax. I'm
414 # really sorry if you're the poor sap who has to maintain this.
415
416 inner_privacy_query = (
417 Union(
418 Select(
419 Archive.id,
420 tables=(Archive,),
421 where=(Archive.private == False)
422 ),
423 Select(
424 Archive.id,
425 tables=(Archive,),
426 where=And(
427 Archive.private == True,
428 Archive.ownerID.is_in(
429 Select(
430 TeamParticipation.teamID,
431 where=(TeamParticipation.person == user),
432 distinct=True
433 )
434 )
435 )
436 )
437 )
438 )
439
412 if user is None:440 if user is None:
413 # Anonymous requests don't get to see private builds at all.441 # Anonymous requests don't get to see private builds at all.
414 origin.extend(left_join_archive)442 extra_clauses.append(
415 extra_clauses.append(Coalesce(Archive.private, False) == False)443 Or(
444 PackageBuild.id == None,
445 PackageBuild.archive_id.is_in(
446 Select(
447 Archive.id,
448 tables=(Archive,),
449 where=(Archive.private == False)
450 )
451 )
452 )
453 )
416454
417 elif user.inTeam(getUtility(ILaunchpadCelebrities).admin):455 elif user.inTeam(getUtility(ILaunchpadCelebrities).admin):
418 # Admins get to see everything.456 # Admins get to see everything.
@@ -420,13 +458,12 @@
420 else:458 else:
421 # Everyone else sees all public builds and the459 # Everyone else sees all public builds and the
422 # specific private builds to which they have access.460 # specific private builds to which they have access.
423 origin.extend(left_join_archive)
424 origin.append(LeftJoin(
425 TeamParticipation,
426 TeamParticipation.teamID == Archive.ownerID))
427 extra_clauses.append(461 extra_clauses.append(
428 Or(Coalesce(Archive.private, False) == False,462 Or(
429 TeamParticipation.person == user))463 PackageBuild.id == None,
464 PackageBuild.archive_id.is_in(inner_privacy_query)
465 )
466 )
430467
431 filtered_builds = IStore(BuildFarmJob).using(*origin).find(468 filtered_builds = IStore(BuildFarmJob).using(*origin).find(
432 BuildFarmJob, *extra_clauses)469 BuildFarmJob, *extra_clauses)