Skip to content

Commit 45d8959

Browse files
committed
fix: Fix invalid depdencies for IDE channel
1 parent cef9ba1 commit 45d8959

File tree

3 files changed

+75
-27
lines changed

3 files changed

+75
-27
lines changed

src/Uno.UI.RemoteControl.Host/IDEChannel/IdeChannelServer.cs

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
using System.IO.Pipes;
33
using System.Threading;
44
using System.Threading.Tasks;
5-
using Microsoft.Extensions.Configuration;
65
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.Options;
77
using StreamJsonRpc;
88
using Uno.Extensions;
99
using Uno.UI.RemoteControl.Messaging.IdeChannel;
@@ -17,22 +17,21 @@ namespace Uno.UI.RemoteControl.Host.IdeChannel;
1717
internal class IdeChannelServer : IIdeChannel, IDisposable
1818
{
1919
private readonly ILogger _logger;
20-
private readonly IConfiguration _configuration;
20+
private readonly IDisposable? _configSubscription;
2121

22-
private readonly Task<bool> _initializeTask;
22+
private Task<bool> _initializeTask;
2323
private NamedPipeServerStream? _pipeServer;
2424
private JsonRpc? _rpcServer;
2525
private Proxy? _proxy;
2626

27-
public IdeChannelServer(ILogger<IdeChannelServer> logger, IConfiguration configuration)
27+
public IdeChannelServer(ILogger<IdeChannelServer> logger, IOptionsMonitor<IdeChannelServerOptions> config)
2828
{
2929
_logger = logger;
30-
_configuration = configuration;
3130

32-
_initializeTask = Task.Run(InitializeServer);
31+
_initializeTask = Task.Run(() => InitializeServer(config.CurrentValue.ChannelId));
32+
_configSubscription = config.OnChange(opts => _initializeTask = InitializeServer(opts.ChannelId));
3333
}
3434

35-
3635
#region IIdeChannel
3736

3837
/// <inheritdoc />
@@ -65,33 +64,63 @@ public async ValueTask<bool> WaitForReady(CancellationToken ct = default)
6564
/// <summary>
6665
/// Initialize as dev-server (cf. IdeChannelClient for init as IDE)
6766
/// </summary>
68-
private async Task<bool> InitializeServer()
67+
private async Task<bool> InitializeServer(Guid channelId)
6968
{
70-
if (!Guid.TryParse(_configuration["ideChannel"], out var ideChannel))
69+
try
7170
{
72-
_logger.LogDebug("No IDE Channel ID specified, skipping.");
73-
return false;
71+
// First we remove the proxy to prevent messages being sent while we are re-initializing
72+
_proxy = null;
73+
74+
// Dispose any existing server
75+
_rpcServer?.Dispose();
76+
if (_pipeServer is { } server)
77+
{
78+
server.Disconnect();
79+
await server.DisposeAsync();
80+
}
81+
}
82+
catch (Exception error)
83+
{
84+
_logger.LogWarning(error, "An error occurred while disposing the existing IDE channel server. Continuing initialization.");
7485
}
86+
87+
try
88+
{
89+
if (channelId == Guid.Empty)
90+
{
91+
return false;
92+
}
7593

76-
_pipeServer = new NamedPipeServerStream(
77-
pipeName: ideChannel.ToString(),
78-
direction: PipeDirection.InOut,
79-
maxNumberOfServerInstances: 1,
80-
transmissionMode: PipeTransmissionMode.Byte,
81-
options: PipeOptions.Asynchronous | PipeOptions.WriteThrough);
94+
_pipeServer = new NamedPipeServerStream(
95+
pipeName: channelId.ToString(),
96+
direction: PipeDirection.InOut,
97+
maxNumberOfServerInstances: 1,
98+
transmissionMode: PipeTransmissionMode.Byte,
99+
options: PipeOptions.Asynchronous | PipeOptions.WriteThrough);
82100

83-
await _pipeServer.WaitForConnectionAsync();
101+
await _pipeServer.WaitForConnectionAsync();
84102

85-
if (_logger.IsEnabled(LogLevel.Debug))
86-
{
87-
_logger.LogDebug("IDE Connected");
88-
}
103+
_proxy = new(this);
104+
_rpcServer = JsonRpc.Attach(_pipeServer, _proxy);
89105

90-
_proxy = new(this);
91-
_rpcServer = JsonRpc.Attach(_pipeServer, _proxy);
106+
if (_logger.IsEnabled(LogLevel.Debug))
107+
{
108+
_logger.LogDebug("IDE channel successfully initialized.");
109+
}
92110

93-
_ = StartKeepAliveAsync();
94-
return true;
111+
_ = StartKeepAliveAsync();
112+
113+
return true;
114+
}
115+
catch (Exception error)
116+
{
117+
if (_logger.IsEnabled(LogLevel.Error))
118+
{
119+
_logger.LogError(error, "Failed to init the IDE channel.");
120+
}
121+
122+
return false;
123+
}
95124
}
96125

97126
private async Task StartKeepAliveAsync()
@@ -108,6 +137,7 @@ private async Task StartKeepAliveAsync()
108137
/// <inheritdoc />
109138
public void Dispose()
110139
{
140+
_configSubscription?.Dispose();
111141
_rpcServer?.Dispose();
112142
_pipeServer?.Dispose();
113143
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace Uno.UI.RemoteControl.Host.IdeChannel;
4+
5+
public class IdeChannelServerOptions
6+
{
7+
public Guid ChannelId { get; set; }
8+
}

src/Uno.UI.RemoteControl.Host/Program.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static async Task Main(string[] args)
3737
var httpPort = 0;
3838
var parentPID = 0;
3939
var solution = default(string);
40+
var ideChannel = Guid.Empty;
4041

4142
var p = new OptionSet
4243
{
@@ -66,7 +67,15 @@ static async Task Main(string[] args)
6667

6768
solution = s;
6869
}
69-
}
70+
},
71+
{
72+
"ideChannel=", s => {
73+
if(!Guid.TryParse(s, out ideChannel))
74+
{
75+
throw new ArgumentException($"The ide channel parameter is invalid {s}");
76+
}
77+
}
78+
},
7079
};
7180

7281
p.Parse(args);
@@ -92,6 +101,7 @@ static async Task Main(string[] args)
92101
.SetMinimumLevel(LogLevel.Debug));
93102

94103
globalServices.AddGlobalTelemetry(); // Global telemetry services (Singleton)
104+
globalServices.AddOptions<IdeChannelServerOptions>().Configure(opts => opts.ChannelId = ideChannel);
95105
globalServices.AddSingleton<IIdeChannel, IdeChannelServer>();
96106

97107
#pragma warning disable ASP0000 // Do not call ConfigureServices after calling UseKestrel.

0 commit comments

Comments
 (0)