madelson/DistributedLock

FileSystem - consider making directory creation invulnerable to transient UnauthorizedAccessException

madelson opened this issue · 1 comments

For file locks, we have this line of code:

                try { System.IO.Directory.CreateDirectory(this.Directory); }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"Failed to ensure that lock file directory {this.Directory} exists", ex);
                }

Very rarely when running TestParallelism, I've seen this fail with UnauthorizedAccessException, presumably due to some form of concurrent directory creation. We can make this less vulnerable by being willing to retry directory creation a certain number of times when hitting that particular exception.

Repro:

var taskCount = 20;
using var barrier = new Barrier(taskCount);

var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

var tasks = Enumerable.Range(0, taskCount)
	.Select(i => Task.Run(() =>
	{
		barrier.SignalAndWait();

		for (var i = 0; i < 1000; ++i)
		{
			try
			{
				Directory.CreateDirectory(path);
				Directory.Delete(path);
			}
			catch (IOException) { }
		}
	}))
	.ToArray();

try
{
	Task.WaitAll(tasks); // fails with UnauthorizedAccessException (wrapped in AggregateException)
}
finally
{
	File.Delete(path);
}