Browse Source

Ensure watched projects are not built in parallel to avoid file locking issues

johluo/lock
John Luo 6 years ago
parent
commit
8093a22c36
  1. 15
      src/Microsoft.Tye.Hosting/Model/Application.cs
  2. 19
      src/Microsoft.Tye.Hosting/ProcessRunner.cs
  3. 5
      src/Microsoft.Tye.Hosting/Watch/DotNetWatcher.cs

15
src/Microsoft.Tye.Hosting/Model/Application.cs

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
namespace Microsoft.Tye.Hosting.Model namespace Microsoft.Tye.Hosting.Model
{ {
@ -17,6 +18,18 @@ namespace Microsoft.Tye.Hosting.Model
Source = source.FullName; Source = source.FullName;
ContextDirectory = source.DirectoryName!; ContextDirectory = source.DirectoryName!;
Services = services; Services = services;
foreach (var s in Services.Values)
{
if (s.Description.RunInfo is ProjectRunInfo projectRunInfo)
{
var projectFileName = projectRunInfo.ProjectFile.FullName;
if (!ProjectFileLocks.ContainsKey(projectFileName))
{
ProjectFileLocks[projectFileName] = new SemaphoreSlim(1, 1);
}
}
}
} }
public string Source { get; } public string Source { get; }
@ -25,6 +38,8 @@ namespace Microsoft.Tye.Hosting.Model
public Dictionary<string, Service> Services { get; } public Dictionary<string, Service> Services { get; }
internal Dictionary<string, SemaphoreSlim> ProjectFileLocks { get; } = new Dictionary<string, SemaphoreSlim>();
public Dictionary<object, object> Items { get; } = new Dictionary<object, object>(); public Dictionary<object, object> Items { get; } = new Dictionary<object, object>();
public string? Network { get; set; } public string? Network { get; set; }

19
src/Microsoft.Tye.Hosting/ProcessRunner.cs

@ -359,9 +359,24 @@ namespace Microsoft.Tye.Hosting
}, },
Build = async () => Build = async () =>
{ {
if (service.Description.RunInfo is ProjectRunInfo) if (service.Description.RunInfo is ProjectRunInfo projectRunInfo)
{ {
var buildResult = await ProcessUtil.RunAsync("dotnet", $"build \"{service.Status.ProjectFilePath}\" /nologo", throwOnError: false, workingDirectory: application.ContextDirectory); ProcessResult buildResult;
var projectFile = projectRunInfo.ProjectFile.FullName;
var projectSemaphore = application.ProjectFileLocks[projectFile];
await projectSemaphore.WaitAsync();
try
{
_logger.LogDebug($"[{replica}] Building project {projectFile}:");
buildResult = await ProcessUtil.RunAsync("dotnet", $"build \"{service.Status.ProjectFilePath}\" /nologo", throwOnError: false, workingDirectory: application.ContextDirectory);
}
finally
{
_logger.LogDebug($"[{replica}] Finished Building project {projectFile}:");
projectSemaphore.Release();
}
if (buildResult.ExitCode != 0) if (buildResult.ExitCode != 0)
{ {
_logger.LogInformation("Building projects failed with exit code {ExitCode}: \r\n" + buildResult.StandardOutput, buildResult.ExitCode); _logger.LogInformation("Building projects failed with exit code {ExitCode}: \r\n" + buildResult.StandardOutput, buildResult.ExitCode);

5
src/Microsoft.Tye.Hosting/Watch/DotNetWatcher.cs

@ -88,7 +88,7 @@ namespace Microsoft.DotNet.Watcher
if (finishedTask == processTask) if (finishedTask == processTask)
{ {
// Now wait for a file to change before restarting process // Now wait for a file to change before restarting process
await fileSetWatcher.GetChangedFileAsync(cancellationToken, () => _logger.LogWarning("Waiting for a file to change before restarting dotnet...")); await fileSetWatcher.GetChangedFileAsync(cancellationToken, () => _logger.LogWarning("watch: {Replica} Waiting for a file to change before restarting dotnet...", replica));
} }
if (!string.IsNullOrEmpty(fileSetTask.Result)) if (!string.IsNullOrEmpty(fileSetTask.Result))
@ -112,7 +112,8 @@ namespace Microsoft.DotNet.Watcher
// Build failed, keep retrying builds until successful build. // Build failed, keep retrying builds until successful build.
} }
await fileSetWatcher.GetChangedFileAsync(cancellationToken, () => _logger.LogWarning("Waiting for a file to change before restarting dotnet...")); // Now wait for a file to change before restarting process
await fileSetWatcher.GetChangedFileAsync(cancellationToken, () => _logger.LogWarning("watch: {Replica} Waiting for a file to change before restarting dotnet...", replica));
} }
} }
} }

Loading…
Cancel
Save