diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index 78e4b59a..4df80ddf 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -532,7 +532,7 @@ sub clone_submit : Chained('build') PathPart('clone/submit') Args(0) { my %currentBuilds; my $newBuild = checkBuild( $c->model('DB'), $build->project, $build->jobset, - $inputInfo, $nixExprInput, $job, \%currentBuilds, undef); + $inputInfo, $nixExprInput, $job, \%currentBuilds, undef, {}); error($c, "This build has already been performed.") unless $newBuild; diff --git a/src/lib/Hydra/Helper/AddBuilds.pm b/src/lib/Hydra/Helper/AddBuilds.pm index e3115218..0fa3ed20 100644 --- a/src/lib/Hydra/Helper/AddBuilds.pm +++ b/src/lib/Hydra/Helper/AddBuilds.pm @@ -803,7 +803,7 @@ sub getPrevJobsetEval { # Check whether to add the build described by $buildInfo. sub checkBuild { - my ($db, $project, $jobset, $inputInfo, $nixExprInput, $buildInfo, $buildIds, $prevEval) = @_; + my ($db, $project, $jobset, $inputInfo, $nixExprInput, $buildInfo, $buildIds, $prevEval, $jobOutPathMap) = @_; my $jobName = $buildInfo->{jobName}; my $drvPath = $buildInfo->{drvPath}; @@ -844,6 +844,14 @@ sub checkBuild { return; } } + + # Prevent multiple builds with the same (job, outPath) from + # being added. + my $prev = $$jobOutPathMap{$job->name . "\t" . $outPath}; + if (defined $prev) { + print STDERR " already scheduled as build ", $prev, "\n"; + return; + } my $time = time(); @@ -886,6 +894,7 @@ sub checkBuild { }); $buildIds->{$build->id} = 1; + $$jobOutPathMap{$job->name . "\t" . $outPath} = $build->id; if ($build->iscachedbuild) { print STDERR " marked as cached build ", $build->id, "\n"; diff --git a/src/script/hydra-evaluator b/src/script/hydra-evaluator index 33d1c8ce..ddf65f8b 100755 --- a/src/script/hydra-evaluator +++ b/src/script/hydra-evaluator @@ -124,6 +124,8 @@ sub checkJobset { my ($jobs, $nixExprInput) = evalJobs($inputInfo, $jobset->nixexprinput, $jobset->nixexprpath); my $evalStop = time; + my $jobOutPathMap = {}; + txn_do($db, sub { my $prevEval = getPrevJobsetEval($db, $jobset, 1); @@ -138,7 +140,7 @@ sub checkJobset { foreach my $job (permute @{$jobs->{job}}) { next if $job->{jobName} eq ""; print STDERR " considering job " . $project->name, ":", $jobset->name, ":", $job->{jobName} . "\n"; - checkBuild($db, $project, $jobset, $inputInfo, $nixExprInput, $job, \%buildIds, $prevEval); + checkBuild($db, $project, $jobset, $inputInfo, $nixExprInput, $job, \%buildIds, $prevEval, $jobOutPathMap); } # Update the last checked times and error messages for each