Fix race between hydra-eval-jobs and hydra-update-gc-roots
If hydra-eval-jobs creates a new root, and hydra-update-gc-roots runs before hydra-evaluator has had a chance to add the corresponding build to the database, then hydra-update-gc-roots will remove the root. If subsequently the Nix garbage collector kicks in, it may remove the build's .drv file before the build is performed. Since evaluation of the Nixpkgs and NixOS jobsets nowadays takes a lot of time (e.g. an hour), the probability of this happening is fairly high. The quick fix is not to delete roots that are less than a day old. So long as evaluation doesn't take longer than a day, this should be fine ;-) Fixes #166.
This commit is contained in:
parent
114f8a26ee
commit
fb5f01097b
|
@ -2,6 +2,7 @@
|
|||
|
||||
use strict;
|
||||
use File::Path;
|
||||
use File::stat;
|
||||
use File::Basename;
|
||||
use Nix::Store;
|
||||
use Hydra::Schema;
|
||||
|
@ -48,9 +49,7 @@ sub keepBuild {
|
|||
}
|
||||
|
||||
|
||||
# Read the current GC roots. We need to do that here so that we don't
|
||||
# delete roots that were added while we were determining the desired
|
||||
# roots.
|
||||
# Read the current GC roots.
|
||||
print STDERR "*** reading current roots...\n";
|
||||
my $gcRootsDir = getGCRootsDir;
|
||||
opendir DIR, $gcRootsDir or die;
|
||||
|
@ -122,14 +121,23 @@ print STDERR "*** removing unneeded GC roots\n";
|
|||
|
||||
my $rootsKept = 0;
|
||||
my $rootsDeleted = 0;
|
||||
my $now = time();
|
||||
|
||||
foreach my $link (@roots) {
|
||||
next if $link eq "." || $link eq "..";
|
||||
my $path = "/nix/store/$link";
|
||||
if (!defined $roots{$path}) {
|
||||
print STDERR "removing root $path\n";
|
||||
$rootsDeleted++;
|
||||
unlink "$gcRootsDir/$link" or warn "cannot remove $gcRootsDir/$link";
|
||||
# Don't delete roots that are less than a day old, to prevent
|
||||
# a race where hydra-eval-jobs has added a root but
|
||||
# hydra-evaluator hasn't added them to the database yet.
|
||||
if (lstat($path)->ctime < $now - 24 * 60 * 60) {
|
||||
print STDERR "removing root $path\n";
|
||||
$rootsDeleted++;
|
||||
unlink "$gcRootsDir/$link" or warn "cannot remove $gcRootsDir/$link";
|
||||
} else {
|
||||
print STDERR "NOT removing recent root $path\n";
|
||||
$rootsKept++;
|
||||
}
|
||||
} else {
|
||||
$rootsKept++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue