forked from lix-project/hydra
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 strict;
|
||||||
use File::Path;
|
use File::Path;
|
||||||
|
use File::stat;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use Nix::Store;
|
use Nix::Store;
|
||||||
use Hydra::Schema;
|
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
|
# Read the current GC roots.
|
||||||
# delete roots that were added while we were determining the desired
|
|
||||||
# roots.
|
|
||||||
print STDERR "*** reading current roots...\n";
|
print STDERR "*** reading current roots...\n";
|
||||||
my $gcRootsDir = getGCRootsDir;
|
my $gcRootsDir = getGCRootsDir;
|
||||||
opendir DIR, $gcRootsDir or die;
|
opendir DIR, $gcRootsDir or die;
|
||||||
|
@ -122,14 +121,23 @@ print STDERR "*** removing unneeded GC roots\n";
|
||||||
|
|
||||||
my $rootsKept = 0;
|
my $rootsKept = 0;
|
||||||
my $rootsDeleted = 0;
|
my $rootsDeleted = 0;
|
||||||
|
my $now = time();
|
||||||
|
|
||||||
foreach my $link (@roots) {
|
foreach my $link (@roots) {
|
||||||
next if $link eq "." || $link eq "..";
|
next if $link eq "." || $link eq "..";
|
||||||
my $path = "/nix/store/$link";
|
my $path = "/nix/store/$link";
|
||||||
if (!defined $roots{$path}) {
|
if (!defined $roots{$path}) {
|
||||||
print STDERR "removing root $path\n";
|
# Don't delete roots that are less than a day old, to prevent
|
||||||
$rootsDeleted++;
|
# a race where hydra-eval-jobs has added a root but
|
||||||
unlink "$gcRootsDir/$link" or warn "cannot remove $gcRootsDir/$link";
|
# 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 {
|
} else {
|
||||||
$rootsKept++;
|
$rootsKept++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue