StoreReplace: POSIX-first Windows replace for the single-file and directory stores

Both store writers call StoreReplace.Replace; the directory store's File.Replace
retry loop and WriteSnapshotAtomically's Exists/Replace/Move block are deleted.
Un-ignores the mesh empty-store race test on Windows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Libby 2026-11-12 21:57:11 +00:00
commit 459da20399
4 changed files with 160 additions and 43 deletions

View file

@ -681,14 +681,7 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore
stream.Flush(true);
}
if (File.Exists(path))
{
ReplaceExistingFile(tempPath, path);
}
else
{
File.Move(tempPath, path);
}
StoreReplace.Replace(tempPath, path);
}
finally
{
@ -746,26 +739,4 @@ public sealed class DirectoryMessagePackBackingStore : CacheBackingStore
}
}
}
private static void ReplaceExistingFile(string sourcePath, string destinationPath)
{
for (var attempt = 0; attempt < 3; attempt++)
{
try
{
File.Replace(sourcePath, destinationPath, null);
return;
}
catch (IOException) when (attempt < 2)
{
Thread.Sleep(10 * (attempt + 1));
}
catch (UnauthorizedAccessException) when (attempt < 2)
{
Thread.Sleep(10 * (attempt + 1));
}
}
File.Replace(sourcePath, destinationPath, null);
}
}