forked from lix-project/hydra
* Big speed-up of the job status page and the channel generation (such
as the manifest). The builds are now determined in one SQL query rather than a zillion ones.
This commit is contained in:
parent
ca11aba074
commit
16a84f4bf5
|
@ -10,9 +10,8 @@ use Hydra::Helper::CatalystUtils;
|
|||
sub jobstatus : Chained('get_builds') PathPart Args(0) {
|
||||
my ($self, $c) = @_;
|
||||
$c->stash->{template} = 'jobstatus.tt';
|
||||
my $jobs = $c->stash->{allJobs};
|
||||
$c->stash->{latestBuilds} =
|
||||
getLatestBuilds($c, ref $jobs eq "ARRAY" ? $jobs : scalar $jobs->search({active => 1}), {});
|
||||
[joinWithResultInfo($c, $c->stash->{jobStatus})->all];
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,12 +32,9 @@ sub all : Chained('get_builds') PathPart {
|
|||
$c->stash->{resultsPerPage} = $resultsPerPage;
|
||||
$c->stash->{totalBuilds} = $nrBuilds;
|
||||
|
||||
$c->stash->{builds} = [$c->stash->{allBuilds}->search(
|
||||
$c->stash->{builds} = [joinWithResultInfo($c, $c->stash->{allBuilds})->search(
|
||||
{ finished => 1 },
|
||||
{ join => 'resultInfo'
|
||||
, '+select' => ["resultInfo.buildstatus", "resultInfo.releasename"]
|
||||
, '+as' => ["buildstatus", "releasename"]
|
||||
, order_by => "timestamp DESC"
|
||||
{ order_by => "timestamp DESC"
|
||||
, rows => $resultsPerPage
|
||||
, page => $page })];
|
||||
}
|
||||
|
@ -49,11 +45,11 @@ sub nix : Chained('get_builds') PathPart('channel') CaptureArgs(1) {
|
|||
eval {
|
||||
if ($channelName eq "latest") {
|
||||
$c->stash->{channelName} = $c->stash->{channelBaseName} . "-latest";
|
||||
getChannelData($c, getLatestBuilds($c, scalar $c->stash->{allJobs}->search({active => 1}), {buildStatus => 0}));
|
||||
getChannelData($c, scalar($c->stash->{latestSucceeded}));
|
||||
}
|
||||
elsif ($channelName eq "all") {
|
||||
$c->stash->{channelName} = $c->stash->{channelBaseName} . "-all";
|
||||
getChannelData($c, [$c->stash->{allBuilds}->all]);
|
||||
getChannelData($c, scalar($c->stash->{allBuilds}));
|
||||
}
|
||||
else {
|
||||
error($c, "Unknown channel `$channelName'.");
|
||||
|
|
|
@ -65,7 +65,7 @@ sub nixexprs : Chained('nix') PathPart('nixexprs.tar.bz2') Args(0) {
|
|||
|
||||
sub name {
|
||||
my ($build) = @_;
|
||||
return $build->resultInfo->releasename || $build->nixname;
|
||||
return $build->get_column('releasename') || $build->nixname;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,9 +30,10 @@ sub overview : Chained('job') PathPart('') Args(0) {
|
|||
sub get_builds : Chained('job') PathPart('') CaptureArgs(0) {
|
||||
my ($self, $c) = @_;
|
||||
$c->stash->{allBuilds} = $c->stash->{job}->builds;
|
||||
#$c->stash->{allJobs} = # !!! horribly hacky
|
||||
# $c->stash->{job}->jobset->jobs->search({name => $c->stash->{job}->name});
|
||||
$c->stash->{allJobs} = [$c->stash->{job}];
|
||||
$c->stash->{jobStatus} = $c->model('DB')->resultset('JobStatusForJob')
|
||||
->search({}, {bind => [$c->stash->{project}->name, $c->stash->{jobset}->name, $c->stash->{job}->name]});
|
||||
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceededForJob')
|
||||
->search({}, {bind => [$c->stash->{project}->name, $c->stash->{jobset}->name, $c->stash->{job}->name]});
|
||||
$c->stash->{channelBaseName} =
|
||||
$c->stash->{project}->name . "-" . $c->stash->{jobset}->name . "-" . $c->stash->{job}->name;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,10 @@ sub index : Chained('jobset') PathPart('') Args(0) {
|
|||
sub get_builds : Chained('jobset') PathPart('') CaptureArgs(0) {
|
||||
my ($self, $c) = @_;
|
||||
$c->stash->{allBuilds} = $c->stash->{jobset}->builds;
|
||||
$c->stash->{allJobs} = $c->stash->{jobset}->jobs;
|
||||
$c->stash->{jobStatus} = $c->model('DB')->resultset('JobStatusForJobset')
|
||||
->search({}, {bind => [$c->stash->{project}->name, $c->stash->{jobset}->name]});
|
||||
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceededForJobset')
|
||||
->search({}, {bind => [$c->stash->{project}->name, $c->stash->{jobset}->name]});
|
||||
$c->stash->{channelBaseName} =
|
||||
$c->stash->{project}->name . "-" . $c->stash->{jobset}->name;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,10 @@ sub updateProject {
|
|||
sub get_builds : Chained('project') PathPart('') CaptureArgs(0) {
|
||||
my ($self, $c) = @_;
|
||||
$c->stash->{allBuilds} = $c->stash->{project}->builds;
|
||||
$c->stash->{allJobs} = $c->stash->{project}->jobs;
|
||||
$c->stash->{jobStatus} = $c->model('DB')->resultset('JobStatusForProject')
|
||||
->search({}, {bind => [$c->stash->{project}->name]});
|
||||
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceededForProject')
|
||||
->search({}, {bind => [$c->stash->{project}->name]});
|
||||
$c->stash->{channelBaseName} = $c->stash->{project}->name;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,8 @@ sub release :Local {
|
|||
sub get_builds : Chained('/') PathPart('') CaptureArgs(0) {
|
||||
my ($self, $c) = @_;
|
||||
$c->stash->{allBuilds} = $c->model('DB::Builds');
|
||||
$c->stash->{allJobs} = $c->model('DB::Jobs');
|
||||
$c->stash->{jobStatus} = $c->model('DB')->resultset('JobStatus');
|
||||
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceeded');
|
||||
$c->stash->{channelBaseName} = "everything";
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use Hydra::Helper::Nix;
|
|||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(
|
||||
getBuild getBuildStats getLatestBuilds getChannelData
|
||||
getBuild getBuildStats joinWithResultInfo getChannelData
|
||||
error notFound
|
||||
requireLogin requireProjectOwner requireAdmin requirePost
|
||||
trim
|
||||
|
@ -43,37 +43,28 @@ sub getBuildStats {
|
|||
}
|
||||
|
||||
|
||||
# Return the latest build for each job.
|
||||
sub getLatestBuilds {
|
||||
my ($c, $jobs, $extraAttrs) = @_;
|
||||
# Add the releaseName and buildStatus attributes from the
|
||||
# BuildResultInfo table for each build.
|
||||
sub joinWithResultInfo {
|
||||
my ($c, $source) = @_;
|
||||
|
||||
my @res = ();
|
||||
|
||||
# !!! this could be done more efficiently.
|
||||
|
||||
foreach my $job (ref $jobs eq "ARRAY" ? @{$jobs} : $jobs->all) {
|
||||
foreach my $system ($job->builds->search({}, {select => ['system'], distinct => 1})) {
|
||||
my ($build) = $job->builds->search(
|
||||
{ finished => 1, system => $system->system, %$extraAttrs },
|
||||
{ join => 'resultInfo', order_by => 'timestamp DESC', rows => 1
|
||||
return $source->search(
|
||||
{ },
|
||||
{ join => 'resultInfo'
|
||||
, '+select' => ["resultInfo.releasename", "resultInfo.buildstatus"]
|
||||
, '+as' => ["releasename", "buildstatus"]
|
||||
});
|
||||
push @res, $build if defined $build;
|
||||
}
|
||||
}
|
||||
|
||||
return [@res];
|
||||
}
|
||||
|
||||
|
||||
sub getChannelData {
|
||||
my ($c, $builds) = @_;
|
||||
|
||||
my @builds2 = joinWithResultInfo($c, $builds)
|
||||
->search_literal("exists (select 1 from buildproducts where build = me.id and type = 'nix-build')");
|
||||
|
||||
my @storePaths = ();
|
||||
foreach my $build (@{$builds}) {
|
||||
# !!! better do this in getLatestBuilds with a join.
|
||||
next unless $build->buildproducts->find({type => "nix-build"});
|
||||
foreach my $build (@builds2) {
|
||||
next unless isValidPath($build->outpath);
|
||||
push @storePaths, $build->outpath;
|
||||
my $pkgName = $build->nixname . "-" . $build->system . "-" . $build->id;
|
||||
|
|
|
@ -102,4 +102,26 @@ __PACKAGE__->belongs_to(
|
|||
{ id => "id" },
|
||||
);
|
||||
|
||||
|
||||
sub makeSource {
|
||||
my ($name, $query) = @_;
|
||||
my $source = __PACKAGE__->result_source_instance();
|
||||
my $new_source = $source->new($source);
|
||||
$new_source->source_name($name);
|
||||
$new_source->name(\ "($query)");
|
||||
Hydra::Schema->register_extra_source($name => $new_source);
|
||||
}
|
||||
|
||||
sub makeQueries {
|
||||
my ($name, $constraint) = @_;
|
||||
makeSource('JobStatus' . $name, "select * from (select project, jobset, job, system, max(timestamp) timestamp from Builds where finished = 1 $constraint group by project, jobset, job, system) natural join Builds");
|
||||
makeSource('LatestSucceeded' . $name, "select * from (select project, jobset, job, system, max(timestamp) timestamp from Builds natural join BuildResultInfo where finished = 1 and buildStatus = 0 $constraint group by project, jobset, job, system) natural join Builds");
|
||||
}
|
||||
|
||||
makeQueries('', "");
|
||||
makeQueries('ForProject', "and project = ?");
|
||||
makeQueries('ForJobset', "and project = ? and jobset = ?");
|
||||
makeQueries('ForJob', "and project = ? and jobset = ? and job = ?");
|
||||
|
||||
|
||||
1;
|
||||
|
|
|
@ -56,7 +56,7 @@ install the package simply by clicking on the packages below.</p>
|
|||
|
||||
<tr class="clickable [% IF odd %] odd [% END; odd = !odd %]" onclick="window.location = '[% uri %]'">
|
||||
<td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td>
|
||||
<td><a href="[% uri %]"><tt>[% build.resultInfo.releasename || build.nixname %]</tt></a></td>
|
||||
<td><a href="[% uri %]"><tt>[% build.get_column('releasename') || build.nixname %]</tt></a></td>
|
||||
<td><tt>[% build.system %]</tt></td>
|
||||
<td>
|
||||
[% IF build.homepage -%]
|
||||
|
|
|
@ -405,3 +405,5 @@ create table ReleaseSetJobs (
|
|||
-- Some indices.
|
||||
create index IndexBuildInputsByBuild on BuildInputs(build);
|
||||
create index IndexBuildInputsByDependency on BuildInputs(dependency);
|
||||
create index IndexBuildsByTimestamp on Builds(timestamp);
|
||||
--create index IndexBuildsByJobAndSystem on Builds(project, jobset, job, system);
|
||||
|
|
Loading…
Reference in a new issue