private ServiceHubRemoteHostClient(
            HostWorkspaceServices services,
            IServiceBroker serviceBroker,
            ServiceBrokerClient serviceBrokerClient,
            HubClient hubClient,
            Stream stream,
            IRemoteServiceCallbackDispatcherProvider callbackDispatcherProvider)
        {
            _connectionPools = new ConnectionPools(
                connectionFactory: (serviceName, pool, cancellationToken) => CreateConnectionImplAsync(serviceName, callbackTarget: null, pool, cancellationToken),
                capacity: ConnectionPoolCapacity);

            // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log:
            services.GetService <IWorkspaceTelemetryService>()?.RegisterUnexpectedExceptionLogger(hubClient.Logger);

            _services                            = services;
            _serviceBroker                       = serviceBroker;
            _serviceBrokerClient                 = serviceBrokerClient;
            _hubClient                           = hubClient;
            _callbackDispatcherProvider          = callbackDispatcherProvider;
            _endPoint                            = new RemoteEndPoint(stream, hubClient.Logger, incomingCallTarget: this);
            _endPoint.Disconnected              += OnDisconnected;
            _endPoint.UnexpectedExceptionThrown += OnUnexpectedExceptionThrown;
            _endPoint.StartListening();

            _assetStorage                = services.GetRequiredService <ISolutionAssetStorageProvider>().AssetStorage;
            _serializer                  = services.GetRequiredService <ISerializerService>();
            _errorReportingService       = services.GetService <IErrorReportingService>();
            _shutdownCancellationService = services.GetService <IRemoteHostClientShutdownCancellationService>();
            _isRemoteHostServerGC        = RemoteHostOptions.IsServiceHubProcessServerGC(services);
            _isRemoteHostCoreClr         = RemoteHostOptions.IsServiceHubProcessCoreClr(services);
        }
        public static async Task <Stream> RequestServiceAsync(
            HostWorkspaceServices services,
            HubClient client,
            RemoteServiceName serviceName,
            CancellationToken cancellationToken)
        {
            var isServerGC = RemoteHostOptions.IsServiceHubProcessServerGC(services);
            var isCoreClr  = RemoteHostOptions.IsServiceHubProcessCoreClr(services);

            // Make sure we are on the thread pool to avoid UI thread dependencies if external code uses ConfigureAwait(true)
            await TaskScheduler.Default;

            var descriptor = new ServiceHub.Client.ServiceDescriptor(serviceName.ToString(isServerGC, isCoreClr));

            try
            {
                return(await client.RequestServiceAsync(descriptor, cancellationToken).ConfigureAwait(false));
            }
            catch (Exception e) when(ReportNonFatalWatson(e, cancellationToken))
            {
                // TODO: Once https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1040692.
                // ServiceHub may throw non-cancellation exceptions if it is called after VS started to shut down,
                // even if our cancellation token is signaled. Cancel the operation and do not report an error in these cases.
                //
                // If ServiceHub did not throw non-cancellation exceptions when cancellation token is signaled,
                // we can assume that these exceptions indicate a failure and should be reported to the user.
                cancellationToken.ThrowIfCancellationRequested();

                services.GetService <IErrorReportingService>()?.ShowRemoteHostCrashedErrorInfo(e);

                // TODO: Propagate the original exception (see https://github.com/dotnet/roslyn/issues/40476)
                throw new SoftCrashException("Unexpected exception from HubClient", e, cancellationToken);
            }
Exemple #3
0
        public static async Task <RemoteHostClient> CreateAsync(
            HostWorkspaceServices services,
            AsynchronousOperationListenerProvider listenerProvider,
            IServiceBroker serviceBroker,
            RemoteServiceCallbackDispatcherRegistry callbackDispatchers,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, KeyValueLogMessage.NoProperty, cancellationToken))
            {
                Logger.Log(FunctionId.RemoteHost_Bitness, KeyValueLogMessage.Create(
                               LogType.Trace,
                               m =>
                {
                    m["64bit"]    = RemoteHostOptions.IsServiceHubProcess64Bit(services);
                    m["ServerGC"] = RemoteHostOptions.IsServiceHubProcessServerGC(services);
                }));

#pragma warning disable ISB001    // Dispose of proxies
#pragma warning disable VSTHRD012 // Provide JoinableTaskFactory where allowed
                var serviceBrokerClient = new ServiceBrokerClient(serviceBroker);
#pragma warning restore

                var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient");

                var remoteHostStream = await RequestServiceAsync(services, hubClient, WellKnownServiceHubService.RemoteHost, cancellationToken).ConfigureAwait(false);

                var client = new ServiceHubRemoteHostClient(services, serviceBroker, serviceBrokerClient, hubClient, remoteHostStream, callbackDispatchers);

                var uiCultureLCID = CultureInfo.CurrentUICulture.LCID;
                var cultureLCID   = CultureInfo.CurrentCulture.LCID;

                // initialize the remote service
                await client._endPoint.InvokeAsync <string>(
                    nameof(IRemoteHostService.InitializeGlobalState),
                    new object?[] { uiCultureLCID, cultureLCID },
                    cancellationToken).ConfigureAwait(false);

                if (AsynchronousOperationListenerProvider.IsEnabled && !IsRpsMachine())
                {
                    await client.TryInvokeAsync <IRemoteAsynchronousOperationListenerService>(
                        (service, cancellationToken) => service.EnableAsync(AsynchronousOperationListenerProvider.IsEnabled, listenerProvider.DiagnosticTokensEnabled, cancellationToken),
                        cancellationToken).ConfigureAwait(false);
                }

                client.Started();
                return(client);
            }
        private ServiceHubRemoteHostClient(
            HostWorkspaceServices services,
            IGlobalOptionService globalOptions,
            ServiceBrokerClient serviceBrokerClient,
            HubClient hubClient,
            IRemoteServiceCallbackDispatcherProvider callbackDispatcherProvider)
        {
            // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log:
            services.GetService <IWorkspaceTelemetryService>()?.RegisterUnexpectedExceptionLogger(hubClient.Logger);

            _services                   = services;
            _serviceBrokerClient        = serviceBrokerClient;
            _hubClient                  = hubClient;
            _callbackDispatcherProvider = callbackDispatcherProvider;

            _assetStorage                = services.GetRequiredService <ISolutionAssetStorageProvider>().AssetStorage;
            _errorReportingService       = services.GetService <IErrorReportingService>();
            _shutdownCancellationService = services.GetService <IRemoteHostClientShutdownCancellationService>();
            _isRemoteHostServerGC        = RemoteHostOptions.IsServiceHubProcessServerGC(globalOptions);
            _isRemoteHostCoreClr         = RemoteHostOptions.IsServiceHubProcessCoreClr(globalOptions);
        }
Exemple #5
0
        public static async Task <RemoteHostClient> CreateAsync(HostWorkspaceServices services, IServiceBroker serviceBroker, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, KeyValueLogMessage.NoProperty, cancellationToken))
            {
                Logger.Log(FunctionId.RemoteHost_Bitness, KeyValueLogMessage.Create(LogType.Trace, m => m["64bit"] = RemoteHostOptions.IsServiceHubProcess64Bit(services)));

#pragma warning disable ISB001    // Dispose of proxies
#pragma warning disable VSTHRD012 // Provide JoinableTaskFactory where allowed
                var serviceBrokerClient = new ServiceBrokerClient(serviceBroker);
#pragma warning restore

                var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient");

                var remoteHostStream = await RequestServiceAsync(services, hubClient, WellKnownServiceHubService.RemoteHost, cancellationToken).ConfigureAwait(false);

                var client = new ServiceHubRemoteHostClient(services, serviceBroker, serviceBrokerClient, hubClient, remoteHostStream);

                var uiCultureLCID = CultureInfo.CurrentUICulture.LCID;
                var cultureLCID   = CultureInfo.CurrentCulture.LCID;

                // initialize the remote service
                await client._endPoint.InvokeAsync <string>(
                    nameof(IRemoteHostService.InitializeGlobalState),
                    new object?[] { uiCultureLCID, cultureLCID },
                    cancellationToken).ConfigureAwait(false);

                client.Started();
                return(client);
            }
        }
        public static async Task <RemoteHostClient> CreateAsync(HostWorkspaceServices services, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, KeyValueLogMessage.NoProperty, cancellationToken))
            {
                Logger.Log(FunctionId.RemoteHost_Bitness, KeyValueLogMessage.Create(LogType.Trace, m => m["64bit"] = RemoteHostOptions.IsServiceHubProcess64Bit(services)));

                // let each client to have unique id so that we can distinguish different clients when service is restarted
                var clientId = $"VS ({Process.GetCurrentProcess().Id}) ({Guid.NewGuid()})";

                var hostGroup = new HostGroup(clientId);
                var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient");

                var remoteHostStream = await RequestServiceAsync(services, hubClient, WellKnownServiceHubService.RemoteHost, hostGroup, cancellationToken).ConfigureAwait(false);

                var client = new ServiceHubRemoteHostClient(services, hubClient, hostGroup, remoteHostStream);

                var uiCultureLCID = CultureInfo.CurrentUICulture.LCID;
                var cultureLCID   = CultureInfo.CurrentCulture.LCID;

                // initialize the remote service
                await client._endPoint.InvokeAsync <string>(
                    nameof(IRemoteHostService.InitializeGlobalState),
                    new object?[] { uiCultureLCID, cultureLCID },
                    cancellationToken).ConfigureAwait(false);

                client.Started();
                return(client);
            }
        }