Fix a huge performance regression in the jobstatus page

The renderBuildStatusIcon function was looking at the
resultInfo and schedulingInfo of each build, causing
a SQL query for every build in the result.
This commit is contained in:
Eelco Dolstra 2011-11-29 19:55:49 +01:00
parent afef502bb6
commit 69e9a91bcb
4 changed files with 27 additions and 22 deletions

View file

@ -16,8 +16,8 @@ sub getJobStatus {
$latest = $latest->search( $latest = $latest->search(
defined $maintainer ? { maintainers => { like => "%$maintainer%" } } : {}, defined $maintainer ? { maintainers => { like => "%$maintainer%" } } : {},
{ '+select' => ["me.statusChangeId", "me.statusChangeTime"] { '+select' => ["me.statusChangeId", "me.statusChangeTime", "resultInfo.buildStatus"]
, '+as' => ["statusChangeId", "statusChangeTime"] , '+as' => ["statusChangeId", "statusChangeTime", "buildStatus"]
, order_by => "coalesce(statusChangeTime, 0) desc" , order_by => "coalesce(statusChangeTime, 0) desc"
}); });
@ -64,11 +64,13 @@ sub all : Chained('get_builds') PathPart {
$c->stash->{resultsPerPage} = $resultsPerPage; $c->stash->{resultsPerPage} = $resultsPerPage;
$c->stash->{totalBuilds} = $nrBuilds; $c->stash->{totalBuilds} = $nrBuilds;
$c->stash->{builds} = [joinWithResultInfo($c, $c->stash->{allBuilds})->search( $c->stash->{builds} = [ joinWithResultInfo($c, $c->stash->{allBuilds})->search(
{ finished => 1 }, { finished => 1 },
{ order_by => "timestamp DESC" { '+select' => ["resultInfo.buildStatus"]
, '+as' => ["buildStatus"]
, order_by => "timestamp DESC"
, rows => $resultsPerPage , rows => $resultsPerPage
, page => $page })]; , page => $page }) ];
} }

View file

@ -25,11 +25,16 @@ sub overview : Chained('job') PathPart('') Args(0) {
#getBuildStats($c, scalar $c->stash->{job}->builds); #getBuildStats($c, scalar $c->stash->{job}->builds);
$c->stash->{currentBuilds} = [$c->stash->{job}->builds->search({iscurrent => 1}, { join => 'resultInfo', '+select' => ["resultInfo.releasename", "resultInfo.buildstatus"] $c->stash->{currentBuilds} = [$c->stash->{job}->builds->search({iscurrent => 1}, { join => 'resultInfo', '+select' => ["resultInfo.releasename", "resultInfo.buildStatus"]
, '+as' => ["releasename", "buildstatus"], order_by => 'system' })]; , '+as' => ["releasename", "buildStatus"], order_by => 'system' })];
$c->stash->{lastBuilds} = [$c->stash->{job}->builds->search({ finished => 1 }, { join => 'resultInfo', '+select' => ["resultInfo.releasename", "resultInfo.buildstatus"] $c->stash->{lastBuilds} =
, '+as' => ["releasename", "buildstatus"], order_by => 'timestamp DESC', rows => 10 })]; [ $c->stash->{job}->builds->search({ finished => 1 },
{ join => 'resultInfo',
, '+select' => ["resultInfo.releasename", "resultInfo.buildStatus"]
, '+as' => ["releasename", "buildStatus"]
, order_by => 'timestamp DESC', rows => 10
}) ];
$c->stash->{runningBuilds} = [$c->stash->{job}->builds->search({busy => 1}, { join => ['schedulingInfo', 'project'] , order_by => ["priority DESC", "timestamp"] $c->stash->{runningBuilds} = [$c->stash->{job}->builds->search({busy => 1}, { join => ['schedulingInfo', 'project'] , order_by => ["priority DESC", "timestamp"]
, '+select' => ['project.enabled', 'schedulingInfo.priority', 'schedulingInfo.disabled', 'schedulingInfo.busy'] , '+select' => ['project.enabled', 'schedulingInfo.priority', 'schedulingInfo.disabled', 'schedulingInfo.busy']

View file

@ -82,7 +82,11 @@ sub jobsetIndex {
# Last builds for jobset. # Last builds for jobset.
my $tmp = $c->stash->{jobset}->builds; my $tmp = $c->stash->{jobset}->builds;
$c->stash->{lastBuilds} = $c->stash->{lastBuilds} =
[ joinWithResultInfo($c, $tmp)->search({ finished => 1 }, { order_by => "timestamp DESC", rows => 5 }) ]; [ joinWithResultInfo($c, $tmp)->search({ finished => 1 },
{ order_by => "timestamp DESC", rows => 5
, '+select' => ["resultInfo.buildStatus"]
, '+as' => ["buildStatus"]
}) ];
} }
sub index : Chained('jobset') PathPart('') Args(0) { sub index : Chained('jobset') PathPart('') Args(0) {

View file

@ -100,7 +100,7 @@
onclick="if(event.which == 2) return true ; window.location = '[% c.uri_for('/build' build.id) %]'"> onclick="if(event.which == 2) return true ; window.location = '[% c.uri_for('/build' build.id) %]'">
[% IF !hideResultInfo %] [% IF !hideResultInfo %]
<td> <td>
[% INCLUDE renderBuildStatusIcon size=16 %] [% INCLUDE renderBuildStatusIcon size=16 busy=(showSchedulingInfo ? 1 : 0) buildstatus=build.get_column('buildStatus') %]
</td> </td>
[% END %] [% END %]
<td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td> <td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td>
@ -203,9 +203,9 @@
[% INCLUDE renderFullJobNameOfBuild build=build %] <a href="[% c.uri_for('/build' build.id) %]">build [% build.id %]</a>[% -%] [% INCLUDE renderFullJobNameOfBuild build=build %] <a href="[% c.uri_for('/build' build.id) %]">build [% build.id %]</a>[% -%]
[% END %] [% END %]
[% BLOCK renderBuildStatusIcon; %] [% BLOCK renderBuildStatusIcon %]
[% finished = build != undef ? build.finished : 1 %] [% finished = build != undef ? build.finished : 1 %]
[% busy = build != undef ? build.schedulingInfo.busy : 0 %] [% busy = busy != undef ? busy : build.schedulingInfo.busy %]
[% buildstatus = buildstatus != undef ? buildstatus : build.resultInfo.buildstatus %] [% buildstatus = buildstatus != undef ? buildstatus : build.resultInfo.buildstatus %]
[% IF finished %] [% IF finished %]
[% IF buildstatus == 0 %] [% IF buildstatus == 0 %]
@ -230,30 +230,24 @@
[% END %] [% END %]
[% END %] [% END %]
[% BLOCK renderStatus; %] [% BLOCK renderStatus %]
[% IF build.finished %] [% IF build.finished %]
[% INCLUDE renderBuildStatusIcon size=16 %]
[% IF build.resultInfo.buildstatus == 0 %] [% IF build.resultInfo.buildstatus == 0 %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<strong>Success</strong> <strong>Success</strong>
[% ELSIF build.resultInfo.buildstatus == 1 %] [% ELSIF build.resultInfo.buildstatus == 1 %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<span class="error">Build returned a non-zero exit code</span> <span class="error">Build returned a non-zero exit code</span>
[% ELSIF build.resultInfo.buildstatus == 2 %] [% ELSIF build.resultInfo.buildstatus == 2 %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<span class="error">A dependency of the build failed</span> <span class="error">A dependency of the build failed</span>
[% ELSIF build.resultInfo.buildstatus == 4 %] [% ELSIF build.resultInfo.buildstatus == 4 %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<span class="error">Cancelled by user</span> <span class="error">Cancelled by user</span>
[% ELSIF build.resultInfo.buildstatus == 5 %] [% ELSIF build.resultInfo.buildstatus == 5 %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<span class="error">Build inhibited because a dependency previously failed to build</span> <span class="error">Build inhibited because a dependency previously failed to build</span>
[% failedDep = build.resultInfo.failedDep %] [% failedDep = build.resultInfo.failedDep %]
(namely, <a href="[% c.uri_for('/build' failedDep.build.id 'nixlog' failedDep.stepnr) %]"><tt>[% failedDep.outpath %]</tt></a>) (namely, <a href="[% c.uri_for('/build' failedDep.build.id 'nixlog' failedDep.stepnr) %]"><tt>[% failedDep.outpath %]</tt></a>)
[% ELSIF build.resultInfo.buildstatus == 6 %] [% ELSIF build.resultInfo.buildstatus == 6 %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<span class="error">Build failed (with result)</span> <span class="error">Build failed (with result)</span>
[% ELSE %] [% ELSE %]
[% INCLUDE renderBuildStatusIcon size=16 %]
<span class="error">Build failed</span> <span class="error">Build failed</span>
(see <a href="#nix-error">below</a>) (see <a href="#nix-error">below</a>)
[% END %] [% END %]