未验证 提交 4bb1ffe5 编写于 作者: H Heejae Chang 提交者: GitHub

add ClientId to RemoteHost so that test window can discover our OOP from thier own OOP (#30333)

上级 c6b7941c
......@@ -29,10 +29,10 @@ public static async Task<RemoteHostClient> CreateAsync(Workspace workspace, bool
var remoteHostStream = await inprocServices.RequestServiceAsync(WellKnownRemoteHostServices.RemoteHostService, cancellationToken).ConfigureAwait(false);
var remotableDataRpc = new RemotableDataJsonRpc(workspace, inprocServices.Logger, await inprocServices.RequestServiceAsync(WellKnownServiceHubServices.SnapshotService, cancellationToken).ConfigureAwait(false));
var instance = new InProcRemoteHostClient(workspace, inprocServices, new ReferenceCountedDisposable<RemotableDataJsonRpc>(remotableDataRpc), remoteHostStream);
var current = CreateClientId(Process.GetCurrentProcess().Id.ToString());
var instance = new InProcRemoteHostClient(current, workspace, inprocServices, new ReferenceCountedDisposable<RemotableDataJsonRpc>(remotableDataRpc), remoteHostStream);
// make sure connection is done right
var current = $"VS ({Process.GetCurrentProcess().Id})";
var telemetrySession = default(string);
var uiCultureLCIDE = 0;
var cultureLCID = 0;
......@@ -49,6 +49,7 @@ public static async Task<RemoteHostClient> CreateAsync(Workspace workspace, bool
}
private InProcRemoteHostClient(
string clientId,
Workspace workspace,
InProcRemoteServices inprocServices,
ReferenceCountedDisposable<RemotableDataJsonRpc> remotableDataRpc,
......@@ -57,6 +58,8 @@ public static async Task<RemoteHostClient> CreateAsync(Workspace workspace, bool
{
Contract.ThrowIfNull(remotableDataRpc);
ClientId = clientId;
_inprocServices = inprocServices;
_remotableDataRpc = remotableDataRpc;
......@@ -76,6 +79,8 @@ public void RegisterService(string name, Func<Stream, IServiceProvider, ServiceH
_inprocServices.RegisterService(name, serviceCreator);
}
public override string ClientId { get; }
public override async Task<Connection> TryCreateConnectionAsync(
string serviceName, object callbackTarget, CancellationToken cancellationToken)
{
......
......@@ -57,6 +57,8 @@ private partial class ConnectionManager
_shutdownLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
}
public HostGroup HostGroup => _hostGroup;
public Task<Connection> TryCreateConnectionAsync(string serviceName, object callbackTarget, CancellationToken cancellationToken)
{
// pool is not enabled by option
......
......@@ -7,7 +7,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Notification;
......@@ -30,8 +29,6 @@ private enum GlobalNotificationState
Finished
}
private static int s_instanceId = 0;
private readonly JsonRpc _rpc;
private readonly ConnectionManager _connectionManager;
......@@ -75,9 +72,7 @@ public static async Task<ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace
try
{
// let each client to have unique id so that we can distinguish different clients when service is restarted
var currentInstanceId = Interlocked.Add(ref s_instanceId, 1);
var current = $"VS ({Process.GetCurrentProcess().Id}) ({currentInstanceId})";
var current = CreateClientId(Process.GetCurrentProcess().Id.ToString());
var hostGroup = new HostGroup(current);
var remoteHostStream = await Connections.RequestServiceAsync(workspace, primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, timeout, cancellationToken).ConfigureAwait(false);
......@@ -133,6 +128,8 @@ public static async Task<ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace
_rpc.StartListening();
}
public override string ClientId => _connectionManager.HostGroup.Id;
public override Task<Connection> TryCreateConnectionAsync(string serviceName, object callbackTarget, CancellationToken cancellationToken)
{
return _connectionManager.TryCreateConnectionAsync(serviceName, callbackTarget, cancellationToken);
......@@ -158,6 +155,15 @@ protected override void OnStopped()
_connectionManager.Shutdown();
}
public HostGroup HostGroup
{
get
{
Debug.Assert(_connectionManager.HostGroup.Id == ClientId);
return _connectionManager.HostGroup;
}
}
private void RegisterGlobalOperationNotifications()
{
var globalOperationService = this.Workspace.Services.GetService<IGlobalOperationNotificationService>();
......@@ -295,4 +301,4 @@ private void OnRpcDisconnected(object sender, JsonRpcDisconnectedEventArgs e)
Stopped();
}
}
}
\ No newline at end of file
}
......@@ -52,6 +52,26 @@ public async Task Enable_Disable()
Assert.Null(disabledClient);
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task ClientId()
{
var service = CreateRemoteHostClientService();
service.Enable();
var client1 = await service.TryGetRemoteHostClientAsync(CancellationToken.None);
var id1 = client1.ClientId;
await service.RequestNewRemoteHostAsync(CancellationToken.None);
var client2 = await service.TryGetRemoteHostClientAsync(CancellationToken.None);
var id2 = client2.ClientId;
Assert.NotEqual(id1, id2);
service.Disable();
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task GlobalAssets()
{
......
......@@ -26,6 +26,14 @@ protected RemoteHostClient(Workspace workspace)
public event EventHandler<bool> StatusChanged;
/// <summary>
/// Return an unique string per client.
///
/// one can use this to distinguish different clients that are connected to different RemoteHosts including
/// cases where 2 external process finding each others
/// </summary>
public abstract string ClientId { get; }
/// <summary>
/// Create <see cref="RemoteHostClient.Connection"/> for the <paramref name="serviceName"/> if possible.
/// otherwise, return null.
......@@ -64,6 +72,11 @@ private void OnStatusChanged(bool started)
StatusChanged?.Invoke(this, started);
}
public static string CreateClientId(string prefix)
{
return $"VS ({prefix}) ({Guid.NewGuid().ToString()})";
}
/// <summary>
/// NoOpClient is used if a user killed our remote host process. Basically this client never
/// create a session
......@@ -75,6 +88,8 @@ public class NoOpClient : RemoteHostClient
{
}
public override string ClientId => nameof(NoOpClient);
public override Task<Connection> TryCreateConnectionAsync(string serviceName, object callbackTarget, CancellationToken cancellationToken)
{
return SpecializedTasks.Default<Connection>();
......@@ -140,7 +155,7 @@ public void Dispose()
// when that happen, we don't want to crash VS, so this is debug only check
if (!Environment.HasShutdownStarted)
{
Debug.Assert(false,
Debug.Assert(false,
$"Unless OOP process (RoslynCodeAnalysisService) is explicitly killed, this should have been disposed!\r\n {_creationCallStack}");
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册