From 2fb2ad419d86b7a224f7b63964a4b66feecc7d92 Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Tue, 28 May 2024 16:25:07 +0700 Subject: [PATCH] Detect situation where empty repo zip uploaded If FinishReset gets an upload of an *empty* Mercurial repo, then WaitForRepoEmptyState could wait forever. To catch that situation 99% of the time, we can simply check for the existence of `00changelog.i` in the Mercurial repo store: that file is guaranteed to exist if the repo has commits, so its absence means an empty repo. To ensure belt-and-suspenders, we still need to implement a timeout in the WaitForRepoEmptyState method, but this is a good start. --- backend/LexBoxApi/Services/HgService.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/LexBoxApi/Services/HgService.cs b/backend/LexBoxApi/Services/HgService.cs index 7899cdac5..ec248f016 100644 --- a/backend/LexBoxApi/Services/HgService.cs +++ b/backend/LexBoxApi/Services/HgService.cs @@ -71,7 +71,6 @@ await Task.Run(() => }); // TODO 789: In theory this shouldn't need an invalidate call? Try with and without await InvalidateDirCache(code); - // await Process.Start("sync").WaitForExitAsync(); // TODO: Put behind an OS check so we don't break Windows await WaitForRepoEmptyState(code, RepoEmptyState.Empty); } @@ -110,8 +109,7 @@ public async Task ResetRepo(string code) await SoftDeleteRepo(code, $"{FileUtils.ToTimestamp(DateTimeOffset.UtcNow)}__reset"); //we must init the repo as uploading a zip is optional tmpRepo.MoveTo(PrefixRepoFilePath(code)); - // await Process.Start("sync").WaitForExitAsync(); // TODO: Put behind an OS check so we don't break Windows - await InvalidateDirCache(code); // TODO 789: Does this work now? + await InvalidateDirCache(code); await WaitForRepoEmptyState(code, RepoEmptyState.Empty); } @@ -147,8 +145,10 @@ await Task.Run(() => await DeleteRepo(code); tempRepo.MoveTo(PrefixRepoFilePath(code)); await InvalidateDirCache(code); - // await Process.Start("sync").WaitForExitAsync(); // TODO: Put behind an OS check so we don't break Windows - await WaitForRepoEmptyState(code, RepoEmptyState.NonEmpty); // TODO: Either catch the case where someone uploaded a .zip of an empty .hg repo, or set a timeout in WaitForRepoEmptyState + // If someone uploaded an *empty* repo, we don't want to wait forever for a non-empty state + var changelogPath = Path.Join(PrefixRepoFilePath(code), ".hg", "store", "00changelog.i"); + var expectedState = File.Exists(changelogPath) ? RepoEmptyState.NonEmpty : RepoEmptyState.Empty; + await WaitForRepoEmptyState(code, expectedState); } ///