From 9fb91460e37b93bd67e6c6e56139d4550cf350fd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 27 Oct 2015 13:43:19 +0100 Subject: [PATCH] Restart jobset evals efficiently Fixes DBIx::Class::Storage::DBI::_dbh_execute(): DBI Exception: DBD::Pg::st execute failed: ERROR: stack depth limit exceeded HINT: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate. [for Statement "UPDATE Builds SET busy = ?, finished = ?, iscachedbuild = ?, locker = ? WHERE ( ( id = ? OR id = ? OR ... --- src/lib/Hydra/Helper/Nix.pm | 38 ++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/lib/Hydra/Helper/Nix.pm b/src/lib/Hydra/Helper/Nix.pm index 14023c78..7243166f 100644 --- a/src/lib/Hydra/Helper/Nix.pm +++ b/src/lib/Hydra/Helper/Nix.pm @@ -442,22 +442,18 @@ sub cancelBuilds($$) { sub restartBuilds($$) { my ($db, $builds) = @_; - my @buildIds; + + $builds = $builds->search({ finished => 1 }); + + foreach my $build ($builds->search({}, { columns => ["drvpath"] })) { + next if !isValidPath($build->drvpath); + registerRoot $build->drvpath; + } + + my $nrRestarted = 0; txn_do($db, sub { - my %paths; - - $builds = $builds->search({ finished => 1 }); - - foreach my $build ($builds->all) { - next if !isValidPath($build->drvpath); - $paths{$_->path} = 1 foreach $build->buildoutputs->all; - $paths{$_->path} = 1 foreach $build->buildstepoutputs->all; - push @buildIds, $build->id; - registerRoot $build->drvpath; - } - - $db->resultset('Builds')->search({ id => \@buildIds })->update( + $nrRestarted = $builds->update( { finished => 0 , busy => 0 , locker => "" @@ -466,14 +462,22 @@ sub restartBuilds($$) { # Reset the stats for the evals to which the builds belongs. # !!! Should do this in a trigger. - $db->resultset('JobsetEvals')->search({ build => \@buildIds }, { join => 'buildIds' })->update({ nrsucceeded => undef }); + $db->resultset('JobsetEvals')->search( + { id => { -in => $builds->search({}, { join => { 'jobsetevalmembers' => 'eval' }, select => "jobsetevalmembers.eval", as => "eval", distinct => 1 })->as_query } + })->update({ nrsucceeded => undef }); # Clear the failed paths cache. # FIXME: Add this to the API. - $db->resultset('FailedPaths')->search({ path => [ keys %paths ]})->delete; + my $cleared = $db->resultset('FailedPaths')->search( + { path => { -in => $builds->search({}, { join => "buildoutputs", select => "buildoutputs.path", as => "path", distinct => 1 })->as_query } + })->delete; + $cleared += $db->resultset('FailedPaths')->search( + { path => { -in => $builds->search({}, { join => "buildstepoutputs", select => "buildstepoutputs.path", as => "path", distinct => 1 })->as_query } + })->delete; + print STDERR "cleared $cleared failed paths\n"; }); - return scalar(@buildIds); + return $nrRestarted; }