Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 35 additions & 24 deletions src/Aspire.Cli/Backchannel/AppHostBackchannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,38 +88,49 @@ await rpc.InvokeWithCancellationAsync(

public async Task ConnectAsync(Process process, string socketPath, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity();

_process = process;

if (_rpcTaskCompletionSource.Task.IsCompleted)
try
{
throw new InvalidOperationException("Already connected to AppHost backchannel.");
using var activity = _activitySource.StartActivity();

_process = process;

if (_rpcTaskCompletionSource.Task.IsCompleted)
{
throw new InvalidOperationException("Already connected to AppHost backchannel.");
}

logger.LogDebug("Connecting to AppHost backchannel at {SocketPath}", socketPath);
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
var endpoint = new UnixDomainSocketEndPoint(socketPath);
await socket.ConnectAsync(endpoint, cancellationToken);
logger.LogDebug("Connected to AppHost backchannel at {SocketPath}", socketPath);

var stream = new NetworkStream(socket, true);
var rpc = JsonRpc.Attach(stream, target);

var capabilities = await rpc.InvokeWithCancellationAsync<string[]>(
"GetCapabilitiesAsync",
Array.Empty<object>(),
cancellationToken);

if (!capabilities.Any(s => s == "baseline.v0"))
{
throw new AppHostIncompatibleException(
$"AppHost is incompatible with the CLI. The AppHost must be updated to a version that supports the baseline.v0 capability.",
"baseline.v0"
);
}

_rpcTaskCompletionSource.SetResult(rpc);
}

logger.LogDebug("Connecting to AppHost backchannel at {SocketPath}", socketPath);
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
var endpoint = new UnixDomainSocketEndPoint(socketPath);
await socket.ConnectAsync(endpoint, cancellationToken);
logger.LogDebug("Connected to AppHost backchannel at {SocketPath}", socketPath);

var stream = new NetworkStream(socket, true);
var rpc = JsonRpc.Attach(stream, target);

var capabilities = await rpc.InvokeWithCancellationAsync<string[]>(
"GetCapabilitiesAsync",
Array.Empty<object>(),
cancellationToken);

if (!capabilities.Any(s => s == "baseline.v0"))
catch (RemoteMethodNotFoundException ex)
{
logger.LogError(ex, "Failed to connect to AppHost backchannel. The AppHost must be updated to a version that supports the baseline.v0 capability.");
throw new AppHostIncompatibleException(
$"AppHost is incompatible with the CLI. The AppHost must be updated to a version that supports the baseline.v0 capability.",
"baseline.v0"
);
}

_rpcTaskCompletionSource.SetResult(rpc);
}

public async Task<string[]> GetPublishersAsync(CancellationToken cancellationToken)
Expand Down
6 changes: 6 additions & 0 deletions src/Aspire.Cli/DotNetCliRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ private async Task StartBackchannelAsync(Process process, string socketPath, Tas

throw;
}
catch (Exception ex)
{
logger.LogError(ex, "An unexpected error occurred while trying to connect to the backchannel.");
backchannelCompletionSource.SetException(ex);
throw;
}

} while (await timer.WaitForNextTickAsync(cancellationToken));
}
Expand Down
Loading