isolate exclusive folder access pattern into separate class
This commit is contained in:
parent
e271b4a818
commit
8ef670161b
1 changed files with 77 additions and 48 deletions
|
@ -138,34 +138,6 @@ namespace Microsoft.DotNet.TestFramework
|
|||
return new DirectoryInfo(Path.Combine(baseDirectory, callingMethod + identifier, _assetName));
|
||||
}
|
||||
|
||||
private IEnumerable<FileInfo> LoadInventory(FileInfo file)
|
||||
{
|
||||
file.Refresh();
|
||||
if (!file.Exists)
|
||||
{
|
||||
throw new ArgumentException("Inventory file should exist.");
|
||||
}
|
||||
|
||||
var inventory = new List<FileInfo>();
|
||||
foreach (var p in File.ReadAllLines(file.FullName))
|
||||
{
|
||||
inventory.Add(new FileInfo(p));
|
||||
}
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
private void SaveInventory(FileInfo file, IEnumerable<FileInfo> inventory)
|
||||
{
|
||||
_dataDirectory.Refresh();
|
||||
if (!_dataDirectory.Exists)
|
||||
{
|
||||
_dataDirectory.Create();
|
||||
}
|
||||
|
||||
File.WriteAllLines(file.FullName, inventory.Select((fi) => fi.FullName).ToList());
|
||||
}
|
||||
|
||||
private IEnumerable<FileInfo> GetFileList()
|
||||
{
|
||||
return _root.GetFiles("*.*", SearchOption.AllDirectories)
|
||||
|
@ -191,27 +163,21 @@ namespace Microsoft.DotNet.TestFramework
|
|||
preInventory = beforeAction();
|
||||
}
|
||||
|
||||
Task.Run(async () => await ConcurrencyUtilities.ExecuteWithFileLockedAsync<object>(
|
||||
_dataDirectory.FullName,
|
||||
lockedToken =>
|
||||
ExclusiveFolderAccess.Do(_dataDirectory, (folder) => {
|
||||
file.Refresh();
|
||||
if (file.Exists)
|
||||
{
|
||||
file.Refresh();
|
||||
if (file.Exists)
|
||||
{
|
||||
inventory = LoadInventory(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
inventory = folder.LoadInventory(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
|
||||
inventory = GetFileList().Where(i => !preInventory.Select(p => p.FullName).Contains(i.FullName));
|
||||
inventory = GetFileList().Where(i => !preInventory.Select(p => p.FullName).Contains(i.FullName));
|
||||
|
||||
SaveInventory(file, inventory);
|
||||
}
|
||||
|
||||
return Task.FromResult(new Object());
|
||||
},
|
||||
CancellationToken.None)).Wait();
|
||||
folder.SaveInventory(file, inventory);
|
||||
}
|
||||
});
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
@ -286,7 +252,10 @@ namespace Microsoft.DotNet.TestFramework
|
|||
return;
|
||||
}
|
||||
|
||||
var trackedFiles = _inventoryFiles.AllInventoryFiles.SelectMany(f => LoadInventory(f));
|
||||
IEnumerable<FileInfo> trackedFiles = null;
|
||||
ExclusiveFolderAccess.Do(_dataDirectory, (folder) => {
|
||||
trackedFiles = _inventoryFiles.AllInventoryFiles.SelectMany(f => folder.LoadInventory(f));
|
||||
});
|
||||
|
||||
var assetFiles = GetFileList();
|
||||
|
||||
|
@ -316,7 +285,7 @@ namespace Microsoft.DotNet.TestFramework
|
|||
return;
|
||||
}
|
||||
|
||||
var updatedSourceFiles = LoadInventory(_inventoryFiles.Source)
|
||||
var updatedSourceFiles = ExclusiveFolderAccess.Read(_inventoryFiles.Source)
|
||||
.Where(f => f.LastWriteTime > earliestDataDirectoryTimestamp);
|
||||
|
||||
if (updatedSourceFiles.Any())
|
||||
|
@ -340,5 +309,65 @@ namespace Microsoft.DotNet.TestFramework
|
|||
throw new DirectoryNotFoundException($"Directory not found at '{_root.FullName}'");
|
||||
}
|
||||
}
|
||||
|
||||
private class ExclusiveFolderAccess
|
||||
{
|
||||
private DirectoryInfo _directory;
|
||||
|
||||
private ExclusiveFolderAccess(DirectoryInfo directory)
|
||||
{
|
||||
_directory = directory;
|
||||
}
|
||||
|
||||
public static void Do(DirectoryInfo directory, Action<ExclusiveFolderAccess> action)
|
||||
{
|
||||
Task.Run(async () => await ConcurrencyUtilities.ExecuteWithFileLockedAsync<object>(
|
||||
directory.FullName,
|
||||
lockedToken =>
|
||||
{
|
||||
action(new ExclusiveFolderAccess(directory));
|
||||
return Task.FromResult(new Object());
|
||||
},
|
||||
CancellationToken.None)).Wait();
|
||||
}
|
||||
|
||||
public static IEnumerable<FileInfo> Read(FileInfo file)
|
||||
{
|
||||
IEnumerable<FileInfo> ret = null;
|
||||
Do(file.Directory, (folder) => {
|
||||
ret = folder.LoadInventory(file);
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public IEnumerable<FileInfo> LoadInventory(FileInfo file)
|
||||
{
|
||||
file.Refresh();
|
||||
if (!file.Exists)
|
||||
{
|
||||
throw new ArgumentException("Inventory file should exist.");
|
||||
}
|
||||
|
||||
var inventory = new List<FileInfo>();
|
||||
foreach (var p in File.ReadAllLines(file.FullName))
|
||||
{
|
||||
inventory.Add(new FileInfo(p));
|
||||
}
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void SaveInventory(FileInfo file, IEnumerable<FileInfo> inventory)
|
||||
{
|
||||
_directory.Refresh();
|
||||
if (!_directory.Exists)
|
||||
{
|
||||
_directory.Create();
|
||||
}
|
||||
|
||||
File.WriteAllLines(file.FullName, inventory.Select((fi) => fi.FullName).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue