refactor: split node agent and Go control plane
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
namespace WxAgent.Core;
|
||||
|
||||
/// <summary>Serializes commands locally and across processes; the OS releases the file handle after a crash.</summary>
|
||||
public sealed class InterprocessCommandGate : IDisposable
|
||||
{
|
||||
private readonly SemaphoreSlim _local = new(1, 1);
|
||||
private readonly string _path;
|
||||
private FileStream? _lease;
|
||||
|
||||
public InterprocessCommandGate(string path)
|
||||
{
|
||||
_path = Path.GetFullPath(path);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(_path)!);
|
||||
}
|
||||
|
||||
public async Task WaitAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _local.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
_lease = new FileStream(_path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
|
||||
return;
|
||||
}
|
||||
catch (IOException exception) when ((exception.HResult & 0xffff) is 11 or 32 or 33)
|
||||
{
|
||||
// EAGAIN on Unix; sharing/lock violation on Windows. Other I/O errors must surface.
|
||||
await Task.Delay(50, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_local.Release();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
try { _lease?.Dispose(); }
|
||||
finally
|
||||
{
|
||||
_lease = null;
|
||||
_local.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_lease?.Dispose();
|
||||
_local.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user