Add IPC backoff/retries and safer disposal

Introduce exponential backoff, jitter and retry logic across IPC components to improve robustness and avoid tight retry loops; make disposal idempotent and add connection guards. Key changes:
- LauncherCoordinatorIpcServer / LauncherIpcServer: add backoff constants, ComputeBackoff(), consecutive error tracking and delayed retries with jitter.
- LanMountainDesktopIpcClient / LauncherIpcClient: add connect retry loops, timeouts, delayed retries, improved error logging, and use ArrayPool for buffered async writes; ensure proper cleanup on failures.
- PublicIpcHostService: add disposed flag, guard OnPeerConnected and Dispose, and clear connected peers on dispose.
- Add many auto-generated commit analysis docs under docs/auto_commit_md and new scripts for analyzing/generating commit docs.
These changes aim to make IPC connection handling more resilient and resource-safe.
This commit is contained in:
lincube
2026-05-07 21:39:21 +08:00
parent 84caca02bf
commit d8f75e86be
159 changed files with 8809 additions and 31 deletions

View File

@@ -10,6 +10,9 @@ internal sealed class LauncherCoordinatorIpcServer : IDisposable
{
private const int LengthPrefixSize = 4;
private const int MaxPayloadLength = 1024 * 1024;
private const int BackoffBaseMs = 250;
private const int BackoffMaxMs = 8000;
private const int BackoffJitterMs = 150;
private readonly string _pipeName;
private readonly Func<LauncherCoordinatorRequest, LauncherCoordinatorStatus, Task<LauncherCoordinatorResponse>> _requestHandler;
private readonly Action<LauncherCoordinatorStatus> _heartbeatHandler;
@@ -78,6 +81,8 @@ internal sealed class LauncherCoordinatorIpcServer : IDisposable
private async Task ListenLoopAsync()
{
var consecutiveErrors = 0;
while (!_cts.IsCancellationRequested)
{
NamedPipeServerStream? server = null;
@@ -94,6 +99,7 @@ internal sealed class LauncherCoordinatorIpcServer : IDisposable
var connectedServer = server;
_ = Task.Run(() => HandleConnectionAsync(connectedServer, _cts.Token), _cts.Token);
server = null;
consecutiveErrors = 0;
}
catch (OperationCanceledException)
{
@@ -101,10 +107,12 @@ internal sealed class LauncherCoordinatorIpcServer : IDisposable
}
catch (Exception ex)
{
Logger.Warn($"Launcher coordinator IPC listener failed: {ex.Message}");
consecutiveErrors++;
var delay = ComputeBackoff(consecutiveErrors);
Logger.Warn($"Launcher coordinator IPC listener failed (attempt {consecutiveErrors}), retrying in {delay}ms: {ex.Message}");
try
{
await Task.Delay(250, _cts.Token).ConfigureAwait(false);
await Task.Delay(delay, _cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
@@ -118,6 +126,14 @@ internal sealed class LauncherCoordinatorIpcServer : IDisposable
}
}
private int ComputeBackoff(int attempt)
{
var exponential = BackoffBaseMs * (1 << Math.Min(attempt - 1, 5));
var capped = Math.Min(exponential, BackoffMaxMs);
var jitter = Random.Shared.Next(0, BackoffJitterMs);
return capped + jitter;
}
private async Task HeartbeatLoopAsync()
{
while (!_cts.IsCancellationRequested)