Francois Gouget : testbot/web: Avoid race conditions when submitting jobs.
Alexandre Julliard
julliard at winehq.org
Tue Sep 25 12:29:48 CDT 2018
Module: tools
Branch: master
Commit: 1597fda2afd17798ab6ed558fa9b686e074805aa
URL: https://source.winehq.org/git/tools.git/?a=commit;h=1597fda2afd17798ab6ed558fa9b686e074805aa
Author: Francois Gouget <fgouget at codeweavers.com>
Date: Tue Sep 25 16:58:05 2018 +0200
testbot/web: Avoid race conditions when submitting jobs.
Rename the patch so one instance of Submit.pl gets exclusive access to
it and only one job gets created.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
testbot/web/Submit.pl | 52 ++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index ae4aca3..9ad8fd5 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -745,13 +745,9 @@ sub OnPrev($)
return $self->{Page} == 3 ? $self->OnPage3Prev() : $self->OnPage2Prev();
}
-sub OnSubmit($)
+sub SubmitJob($$$)
{
- my ($self) = @_;
-
- return !1 if (!$self->Validate());
- my $BaseName = $self->ValidateAndGetFileName("FileName");
- return !1 if (!$BaseName);
+ my ($self, $BaseName, $Staging) = @_;
# See also Patches::Submit() in lib/WineTestBot/Patches.pm
@@ -778,11 +774,7 @@ sub OnSubmit($)
# Add steps and tasks for the 32 and 64-bit tests
my $FileType = $self->GetParam("FileType");
my $Impacts;
- if ($FileType eq "patch")
- {
- my $TmpStagingFullPath = $self->GetTmpStagingFullPath($BaseName);
- $Impacts = GetPatchImpacts($TmpStagingFullPath);
- }
+ $Impacts = GetPatchImpacts($Staging) if ($FileType eq "patch");
my $BuildStep;
foreach my $Bits ("32", "64")
@@ -913,8 +905,7 @@ sub OnSubmit($)
}
# Stage the test patch/executable so the job can pick it up
- my $TmpStagingFullPath = $self->GetTmpStagingFullPath($BaseName);
- if (!rename($TmpStagingFullPath, "$DataDir/staging/job". $NewJob->Id ."_$BaseName"))
+ if (!rename($Staging, "$DataDir/staging/job". $NewJob->Id ."_$BaseName"))
{
$self->{ErrMessage} = "Could not stage '$BaseName': $!\n";
return !1;
@@ -943,6 +934,41 @@ sub OnSubmit($)
exit;
}
+sub OnSubmit($)
+{
+ my ($self) = @_;
+
+ return !1 if (!$self->Validate());
+ my $BaseName = $self->ValidateAndGetFileName("FileName");
+ return !1 if (!$BaseName);
+
+ # Rename the staging file to avoid race conditions if the user clicks on
+ # Submit multiple times
+ my $OldStaging = $self->GetTmpStagingFullPath($BaseName);
+ my $Staging = CreateNewLink($OldStaging, "$DataDir/staging", $BaseName);
+ if (!defined $Staging)
+ {
+ $self->{ErrMessage} = "Could not rename '$BaseName': $!";
+ return !1;
+ }
+ if (!unlink $OldStaging)
+ {
+ unlink $Staging;
+ $self->{ErrMessage} = $!{ENOENT} ?
+ "$BaseName has already been submitted or has expired" :
+ "Could not remove the staging '$BaseName' file: $!";
+ return !1;
+ }
+
+ if (!$self->SubmitJob($BaseName, $Staging))
+ {
+ # Restore the file for the next attempt
+ rename($Staging, $OldStaging);
+ return !1;
+ }
+ return 1;
+}
+
sub OnShowAllVMs($)
{
my ($self) = @_;
More information about the wine-cvs
mailing list