Guard against multiple run invocations

This commit is contained in:
Matt Parker
2025-08-08 00:29:50 +10:00
parent 995449c6d1
commit 8f0dd5c1cf

View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Collections.Concurrent;
using System.Diagnostics;
using Ardalis.GuardClauses;
using AsyncReadProcess.Common;
using AsyncReadProcess;
@@ -9,14 +10,18 @@ namespace SharpIDE.Application.Features.Run;
public class RunService
{
public HashSet<SharpIdeProjectModel> RunningProjects { get; } = [];
// TODO: optimise this Copilot junk
private readonly ConcurrentDictionary<SharpIdeProjectModel, SemaphoreSlim> _projectLocks = [];
public async Task RunProject(SharpIdeProjectModel project)
{
Guard.Against.Null(project, nameof(project));
Guard.Against.NullOrWhiteSpace(project.FilePath, nameof(project.FilePath), "Project file path cannot be null or empty.");
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
var semaphoreSlim = _projectLocks.GetOrAdd(project, new SemaphoreSlim(1, 1));
var waitResult = await semaphoreSlim.WaitAsync(0);
if (waitResult is false) throw new InvalidOperationException($"Project {project.Name} is already running.");
try
{
var processStartInfo = new ProcessStartInfo2
{
FileName = "dotnet",
@@ -49,4 +54,9 @@ public class RunService
Console.WriteLine("Project ran successfully.");
}
finally
{
semaphoreSlim.Release();
}
}
}