From 7264e8f1f4a7841c4daf414a73e8345eb6793660 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 2 May 2026 13:55:25 +0000
Subject: [PATCH 1/3] Initial plan
From e76722a3a3bad97b0c49a8a797e3c344d7a3425e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 2 May 2026 13:57:38 +0000
Subject: [PATCH 2/3] Update OpenTelemetry.Exporter packages to 1.15.3 to fix
GHSA-4625-4j76-fww9
Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/2a25fc1c-dd69-4762-a4d7-4c87cf614e29
Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>
---
Directory.Packages.props | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 18035c3..8636062 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -18,8 +18,8 @@
-
-
+
+
From d5468d538a54683846946bc0543df18bdba666f8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 2 May 2026 23:51:11 +0000
Subject: [PATCH 3/3] Add startup retry loop for transient WebView2
resource-in-use crash
Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/7c9c8221-a900-4e4d-8207-7eb2718f58c6
Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>
---
.../Host/AdaptiveRemoteHost.Builder.cs | 45 ++++++++++++++++++-
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/test/AdaptiveRemote.EndtoEndTests.TestServices/Host/AdaptiveRemoteHost.Builder.cs b/test/AdaptiveRemote.EndtoEndTests.TestServices/Host/AdaptiveRemoteHost.Builder.cs
index 99409c9..2890f01 100644
--- a/test/AdaptiveRemote.EndtoEndTests.TestServices/Host/AdaptiveRemoteHost.Builder.cs
+++ b/test/AdaptiveRemote.EndtoEndTests.TestServices/Host/AdaptiveRemoteHost.Builder.cs
@@ -13,6 +13,9 @@ public partial class AdaptiveRemoteHost
{
public class Builder
{
+ private const string ResourceInUseExceptionMessage = "The requested resource is in use.";
+ private const int StartupRetryCount = 3;
+
private AdaptiveRemoteHostSettings _settings;
private readonly ILoggerFactory _loggerFactory;
private readonly HostApplicationLoggerProvider _hostLoggerProvider;
@@ -48,7 +51,35 @@ public AdaptiveRemoteHost Start(Func retryLogger = _loggerFactory.CreateLogger();
+
+ // Only HostStartupException instances whose CapturedOutput contains ResourceInUseExceptionMessage
+ // are retried. Any other exception (e.g. Inconclusive, process-launch failure) propagates immediately.
+ for (int attempt = 1; attempt <= StartupRetryCount; attempt++)
+ {
+ try
+ {
+ return StartWithSettings(effectiveSettings);
+ }
+ catch (HostStartupException ex) when (ex.CapturedOutput.Contains(ResourceInUseExceptionMessage, StringComparison.OrdinalIgnoreCase))
+ {
+ if (attempt == StartupRetryCount)
+ {
+ throw;
+ }
+
+ retryLogger.LogWarning(
+ "Host startup attempt {Attempt}/{MaxAttempts} failed with '{ExceptionMessage}'. Retrying...",
+ attempt, StartupRetryCount, ResourceInUseExceptionMessage);
+ Thread.Sleep(Random.Shared.Next(1000, 3000));
+ }
+ }
+
+ // Unreachable: the loop always exits via return (success) or throw (final-attempt failure
+ // re-throws via the catch block, or a non-retryable exception propagates immediately).
+ // Required by the compiler since it cannot prove the loop body always returns or throws.
+ throw new InvalidOperationException("Unexpected state: startup retry loop exited without returning or throwing.");
}
private AdaptiveRemoteHost StartWithSettings(AdaptiveRemoteHostSettings _settings)
@@ -268,7 +299,7 @@ Failed to connect to the test control endpoint on port {ControlPort} within {Sta
logger.LogError(processException, "Failed to kill the host process. {ErrorMessage}", processException.Message);
}
- throw;
+ throw new HostStartupException(ex.Message, ex, standardOutputAndError.ToString());
}
}
@@ -280,6 +311,16 @@ private static int GetAvailablePort()
listener.Stop();
return port;
}
+
+ private sealed class HostStartupException(string message, Exception innerException, string capturedOutput)
+ : Exception(message, innerException)
+ {
+ ///
+ /// The captured stdout/stderr from the host process at the time of the startup failure.
+ /// Used by to identify retryable crashes (e.g., WebView2 resource-in-use).
+ ///
+ internal string CapturedOutput { get; } = capturedOutput;
+ }
}
}