* Hack around those SQLite timeouts: just retry the transaction.

This commit is contained in:
Eelco Dolstra
2009-04-22 22:43:04 +00:00
parent 80691a39f5
commit 97a6011628
8 changed files with 49 additions and 33 deletions

View File

@ -273,7 +273,7 @@ sub restart : Chained('build') PathPart Args(0) {
requireProjectOwner($c, $build->project);
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
error($c, "This build cannot be restarted.")
unless $build->finished &&
($build->resultInfo->buildstatus == 3 ||
@ -304,7 +304,7 @@ sub cancel : Chained('build') PathPart Args(0) {
requireProjectOwner($c, $build->project);
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
error($c, "This build cannot be cancelled.")
if $build->finished || $build->schedulingInfo->busy;
@ -340,7 +340,7 @@ sub keep : Chained('build') PathPart Args(1) {
registerRoot $build->outpath if $newStatus == 1;
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
$build->resultInfo->update({keep => int $newStatus});
});

View File

@ -64,7 +64,7 @@ sub submit : Chained('jobset') PathPart Args(0) {
requireProjectOwner($c, $c->stash->{project});
requirePost($c);
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
updateJobset($c, $c->stash->{jobset});
});
@ -79,7 +79,7 @@ sub delete : Chained('jobset') PathPart Args(0) {
requireProjectOwner($c, $c->stash->{project});
requirePost($c);
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
$c->stash->{jobset}->delete;
});

View File

@ -44,7 +44,7 @@ sub submit : Chained('project') PathPart Args(0) {
requireProjectOwner($c, $c->stash->{project});
requirePost($c);
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
updateProject($c, $c->stash->{project});
});
@ -58,7 +58,7 @@ sub delete : Chained('project') PathPart Args(0) {
requireProjectOwner($c, $c->stash->{project});
requirePost($c);
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
$c->stash->{project}->delete;
});
@ -94,7 +94,7 @@ sub create_submit : Path('/create-project/submit') {
my $projectName = trim $c->request->params->{name};
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
# Note: $projectName is validated in updateProject,
# which will abort the transaction if the name isn't
# valid. Idem for the owner.
@ -127,7 +127,7 @@ sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') A
my $jobsetName = trim $c->request->params->{name};
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
# Note: $jobsetName is validated in updateProject, which will
# abort the transaction if the name isn't valid.
my $jobset = $c->stash->{project}->jobsets->create(

View File

@ -146,14 +146,14 @@ sub releases :Local {
}
elsif ($subcommand eq "submit") {
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
updateReleaseSet($c, $releaseSet);
});
return $c->res->redirect($c->uri_for("/releases", $projectName, $releaseSet->name));
}
elsif ($subcommand eq "delete") {
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
$releaseSet->delete;
});
return $c->res->redirect($c->uri_for($c->controller('Project')->action_for('view'), [$project->name]));
@ -181,7 +181,7 @@ sub create_releaseset :Local {
if (defined $subcommand && $subcommand eq "submit") {
my $releaseSetName = $c->request->params->{name};
$c->model('DB')->schema->txn_do(sub {
txn_do($c->model('DB')->schema, sub {
# Note: $releaseSetName is validated in updateProject,
# which will abort the transaction if the name isn't
# valid.

View File

@ -8,7 +8,7 @@ use File::Basename;
our @ISA = qw(Exporter);
our @EXPORT = qw(
isValidPath queryPathInfo
getHydraPath getHydraDBPath openHydraDB
getHydraPath getHydraDBPath openHydraDB txn_do
registerRoot getGCRootsDir gcRootFor
getPrimaryBuildsForReleaseSet getRelease getLatestSuccessfulRelease );
@ -78,6 +78,21 @@ sub openHydraDB {
}
# Awful hack to handle timeouts in SQLite: just retry the transaction.
# DBD::SQLite *has* a 30 second retry window, but apparently it
# doesn't work.
sub txn_do {
my ($db, $coderef) = @_;
while (1) {
eval {
$db->txn_do($coderef);
};
last if !$@;
die $@ unless $@ =~ "database is locked";
}
}
sub getGCRootsDir {
die unless defined $ENV{LOGNAME};
my $dir = "/nix/var/nix/gcroots/per-user/$ENV{LOGNAME}/hydra-roots";