コード例 #1
0
        public static async Task <RemoteHostClient?> CreateAsync(
            Workspace workspace, CancellationToken cancellationToken)
        {
            try
            {
                using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken))
                {
                    var primary = new HubClient("ManagedLanguage.IDE.RemoteHostClient");
                    var timeout = TimeSpan.FromMilliseconds(workspace.Options.GetOption(RemoteHostOptions.RequestServiceTimeoutInMS));

                    // Retry (with timeout) until we can connect to RemoteHost (service hub process).
                    // we are seeing cases where we failed to connect to service hub process when a machine is under heavy load.
                    // (see https://devdiv.visualstudio.com/DevDiv/_workitems/edit/481103 as one of example)
                    var instance = await Connections.RetryRemoteCallAsync <IOException, ServiceHubRemoteHostClient>(
                        workspace, () => CreateWorkerAsync(workspace, primary, timeout, cancellationToken), timeout, cancellationToken).ConfigureAwait(false);

                    instance.Started();

                    // return instance
                    return(instance);
                }
            }
            catch (SoftCrashException)
            {
                // at this point, we should have shown info bar (RemoteHostCrashInfoBar.ShowInfoBar) to users
                // returning null here will disable OOP for this VS session.
                // * Note * this is not trying to recover the exception. but giving users to time
                // to clean up before restart VS
                return(null);
            }
        }
コード例 #2
0
        public static async Task <Stream> RequestServiceAsync(
            Workspace workspace,
            HubClient client,
            string serviceName,
            HostGroup hostGroup,
            CancellationToken cancellationToken)
        {
            const string LogMessage = "Unexpected exception from HubClient";

            var descriptor = new ServiceDescriptor(serviceName)
            {
                HostGroup = hostGroup
            };

            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();

                client.Logger.TraceEvent(TraceEventType.Error, 1, $"{LogMessage}: {e}");

                RemoteHostCrashInfoBar.ShowInfoBar(workspace, e);

                // TODO: Propagate the original exception (see https://github.com/dotnet/roslyn/issues/40476)
                throw new SoftCrashException(LogMessage, e, cancellationToken);
            }
        public override bool TryGetWorkspace(ITextBuffer textBuffer, out Workspace workspace)
        {
            if (textBuffer == null)
            {
                throw new ArgumentNullException(nameof(textBuffer));
            }

            // We do a best effort approach in this method to get the workspace that belongs to the TextBuffer.
            // Below we try and find the project and then the solution that contains the given text buffer. If
            // we're able to find both the project and solution then we use the solution to look up the corresponding
            // Workspace using MonoDevelops TypeSystemService.

            var hostProject = (DotNetProject)_projectService.GetHostProject(textBuffer);

            if (hostProject == null)
            {
                // Does not have a host project.
                workspace = null;
                return(false);
            }

            var hostSolution = hostProject.ParentSolution;

            if (hostSolution == null)
            {
                // Project does not have a solution
                workspace = null;
                return(false);
            }

            return(TryGetWorkspace(hostSolution, out workspace));
        }
コード例 #4
0
        public RoslynMetadataProviderStub(DTE dte)
        {
            var solutionPath = dte.Solution.FullName;
            var msBuildWorkspace = MSBuildWorkspace.Create();

            // ReSharper disable once UnusedVariable
            var solution = msBuildWorkspace.OpenSolutionAsync(solutionPath).Result;

            this.workspace = msBuildWorkspace;
        }
コード例 #5
0
        public RoslynMetadataProviderStub(DTE dte)
        {
            var solutionPath     = dte.Solution.FullName;
            var msBuildWorkspace = MSBuildWorkspace.Create();

            // ReSharper disable once UnusedVariable
            var solution = msBuildWorkspace.OpenSolutionAsync(solutionPath).Result;

            this.workspace = msBuildWorkspace;
        }
コード例 #6
0
        public RoslynProviderStub()
        {
            //var componentModel = ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel)) as IComponentModel;
            //this.workspace = componentModel.GetService<VisualStudioWorkspace>();

            var solutionPath = @"C:\Dev\Typewriter\Typewriter\Typewriter.sln";
            var msBuildWorkspace = MSBuildWorkspace.Create();
            var solution = msBuildWorkspace.OpenSolutionAsync(solutionPath).Result;

            this.workspace = msBuildWorkspace;
        }
コード例 #7
0
        public static async Task <RemoteHostClient?> CreateAsync(Workspace workspace, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken))
            {
                var enableConnectionPool = workspace.Options.GetOption(RemoteHostOptions.EnableConnectionPool);
                var maxConnection        = workspace.Options.GetOption(RemoteHostOptions.MaxPoolConnection);

                // let each client to have unique id so that we can distinguish different clients when service is restarted
                var clientId = CreateClientId(Process.GetCurrentProcess().Id.ToString());

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

                // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log:
                WatsonReporter.InitializeLogger(hubClient.Logger);

                // Create the RemotableDataJsonRpc before we create the remote host: this call implicitly sets up the remote IExperimentationService so that will be available for later calls
                var snapshotServiceStream = await RequestServiceAsync(workspace, hubClient, WellKnownServiceHubServices.SnapshotService, hostGroup, cancellationToken).ConfigureAwait(false);

                var remoteHostStream = await RequestServiceAsync(workspace, hubClient, WellKnownRemoteHostServices.RemoteHostService, hostGroup, cancellationToken).ConfigureAwait(false);

                var remotableDataRpc  = new RemotableDataJsonRpc(workspace, hubClient.Logger, snapshotServiceStream);
                var connectionManager = new ConnectionManager(workspace, hubClient, hostGroup, enableConnectionPool, maxConnection, new ReferenceCountedDisposable <RemotableDataJsonRpc>(remotableDataRpc));

                var client = new ServiceHubRemoteHostClient(workspace, hubClient.Logger, connectionManager, remoteHostStream);

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

                bool success = false;
                try
                {
                    // initialize the remote service
                    _ = await client._endPoint.InvokeAsync <string>(
                        nameof(IRemoteHostService.Connect),
                        new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() },
                        cancellationToken).ConfigureAwait(false);

                    success = true;
                }
                finally
                {
                    if (!success)
                    {
                        client.Dispose();
                    }
                }

                client.Started();
                return(client);
            }
        }
コード例 #8
0
        public static async Task <ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace workspace, HubClient primary, TimeSpan timeout, CancellationToken cancellationToken)
        {
            ServiceHubRemoteHostClient?client = null;

            try
            {
                // let each client to have unique id so that we can distinguish different clients when service is restarted
                var current = CreateClientId(Process.GetCurrentProcess().Id.ToString());

                var hostGroup = new HostGroup(current);

                // Create the RemotableDataJsonRpc before we create the remote host: this call implicitly sets up the remote IExperimentationService so that will be available for later calls
                var remotableDataRpc = new RemotableDataJsonRpc(
                    workspace, primary.Logger,
                    await Connections.RequestServiceAsync(workspace, primary, WellKnownServiceHubServices.SnapshotService, hostGroup, timeout, cancellationToken).ConfigureAwait(false));

                var remoteHostStream = await Connections.RequestServiceAsync(workspace, primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, timeout, cancellationToken).ConfigureAwait(false);

                var enableConnectionPool = workspace.Options.GetOption(RemoteHostOptions.EnableConnectionPool);
                var maxConnection        = workspace.Options.GetOption(RemoteHostOptions.MaxPoolConnection);

                var connectionManager = new ConnectionManager(primary, hostGroup, enableConnectionPool, maxConnection, timeout, new ReferenceCountedDisposable <RemotableDataJsonRpc>(remotableDataRpc));

                client = new ServiceHubRemoteHostClient(workspace, primary.Logger, connectionManager, remoteHostStream);

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

                // make sure connection is done right
                var host = await client._rpc.InvokeWithCancellationAsync <string>(
                    nameof(IRemoteHostService.Connect), new object[] { current, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false);

                return(client);
            }
            catch (ConnectionLostException ex)
            {
                RemoteHostCrashInfoBar.ShowInfoBar(workspace, ex);

                Shutdown(client, ex, cancellationToken);

                // dont crash VS because OOP is failed to start. we will show info bar telling users to restart
                // but never physically crash VS.
                throw new SoftCrashException("Connection Lost", ex, cancellationToken);
            }
            catch (Exception ex)
            {
                Shutdown(client, ex, cancellationToken);
                throw;
            }
コード例 #9
0
        public RoslynMetadataProviderStub(DTE dte)
        {
            var solutionPath     = dte.Solution.FullName;
            var msBuildWorkspace = MSBuildWorkspace.Create();

            msBuildWorkspace.OpenSolutionAsync(solutionPath).GetAwaiter().GetResult();

            // ReSharper disable once UnusedVariable
            //ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            //{
            //    await msBuildWorkspace.OpenSolutionAsync(solutionPath);
            //}).Join();

            this.workspace = msBuildWorkspace;
        }
コード例 #10
0
        private ServiceHubRemoteHostClient(
            Workspace workspace,
            TraceSource logger,
            ConnectionManager connectionManager,
            Stream stream)
            : base(workspace)
        {
            _shutdownCancellationTokenSource = new CancellationTokenSource();

            _connectionManager = connectionManager;

            _endPoint = new RemoteEndPoint(stream, logger, incomingCallTarget: this);
            _endPoint.Disconnected += OnDisconnected;
            _endPoint.UnexpectedExceptionThrown += OnUnexpectedExceptionThrown;
            _endPoint.StartListening();
        }
コード例 #11
0
 internal static void InformDocumentOpen(Microsoft.CodeAnalysis.Workspace ws, Microsoft.CodeAnalysis.DocumentId analysisDocument, TextEditor editor, DocumentContext context)
 {
     if (ws == null)
     {
         throw new ArgumentNullException(nameof(ws));
     }
     if (analysisDocument == null)
     {
         throw new ArgumentNullException(nameof(analysisDocument));
     }
     if (editor == null)
     {
         throw new ArgumentNullException(nameof(editor));
     }
     ((MonoDevelopWorkspace)ws).InformDocumentOpen(analysisDocument, editor, context);
 }
コード例 #12
0
        public override bool TryGetWorkspace(ITextBuffer textBuffer, out Workspace workspace)
        {
            if (textBuffer == null)
            {
                throw new ArgumentNullException(nameof(textBuffer));
            }

            // We do a best effort approach in this method to get the workspace that belongs to the TextBuffer.
            // Below we try and find the project and then the solution that contains the given text buffer. If
            // we're able to find both the project and solution then we use the solution to look up the corresponding
            // Workspace using MonoDevelops TypeSystemService.

            var hostProject = (DotNetProject)_projectService.GetHostProject(textBuffer);

            if (hostProject == null)
            {
                // Does not have a host project.
                workspace = null;
                return(false);
            }

            var hostSolution = hostProject.ParentSolution;

            if (hostSolution == null)
            {
                // Project does not have a solution
                workspace = null;
                return(false);
            }

            workspace = TypeSystemService.GetWorkspace(hostSolution);

            // Workspace cannot be null at this point. If TypeSystemService.GetWorkspace isn't able to find a corresponding
            // workspace it returns an empty workspace. Therefore, in order to see if we have a valid workspace we need to
            // cross-check it against the list of active non-empty workspaces.

            if (!TypeSystemService.AllWorkspaces.Contains(workspace))
            {
                // We were returned the empty workspace which is equivalent to us not finding a valid workspace for our text buffer.
                workspace = null;
                return(false);
            }

            return(true);
        }
コード例 #13
0
        private ServiceHubRemoteHostClient(
            Workspace workspace,
            TraceSource logger,
            ConnectionManager connectionManager,
            Stream stream)
            : base(workspace)
        {
            _shutdownCancellationTokenSource = new CancellationTokenSource();

            _connectionManager = connectionManager;

            _rpc = stream.CreateStreamJsonRpc(target: this, logger);

            // handle disconnected situation
            _rpc.Disconnected += OnRpcDisconnected;

            _rpc.StartListening();
        }
        public override bool TryGetWorkspace(Solution solution, out Workspace workspace)
        {
            if (solution == null)
            {
                throw new ArgumentNullException(nameof(solution));
            }

            workspace = TypeSystemService.GetWorkspace(solution);

            // Workspace cannot be null at this point. If TypeSystemService.GetWorkspace isn't able to find a corresponding
            // workspace it returns an empty workspace. Therefore, in order to see if we have a valid workspace we need to
            // cross-check it against the list of active non-empty workspaces.

            if (!TypeSystemService.AllWorkspaces.Contains(workspace))
            {
                // We were returned the empty workspace which is equivalent to us not finding a valid workspace for our text buffer.
                workspace = null;
                return(false);
            }

            return(true);
        }
コード例 #15
0
 public RoslynContextActionProvider(Microsoft.CodeAnalysis.Workspace workspace, ICodeFixService codeFixService)
 {
     _codeFixService = codeFixService;
     _workspace      = workspace;
 }
コード例 #16
0
        public static async Task <RemoteHostClient?> CreateAsync(Workspace workspace, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken))
            {
                var timeout = TimeSpan.FromMilliseconds(workspace.Options.GetOption(RemoteHostOptions.RequestServiceTimeoutInMS));
                var enableConnectionPool = workspace.Options.GetOption(RemoteHostOptions.EnableConnectionPool);
                var maxConnection        = workspace.Options.GetOption(RemoteHostOptions.MaxPoolConnection);

                // let each client to have unique id so that we can distinguish different clients when service is restarted
                var clientId = CreateClientId(Process.GetCurrentProcess().Id.ToString());

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

                ServiceHubRemoteHostClient?client = null;
                try
                {
                    // Create the RemotableDataJsonRpc before we create the remote host: this call implicitly sets up the remote IExperimentationService so that will be available for later calls
                    var snapshotServiceStream = await Connections.RequestServiceAsync(workspace, primary, WellKnownServiceHubServices.SnapshotService, hostGroup, timeout, cancellationToken).ConfigureAwait(false);

                    var remoteHostStream = await Connections.RequestServiceAsync(workspace, primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, timeout, cancellationToken).ConfigureAwait(false);

                    var remotableDataRpc  = new RemotableDataJsonRpc(workspace, primary.Logger, snapshotServiceStream);
                    var connectionManager = new ConnectionManager(primary, hostGroup, enableConnectionPool, maxConnection, timeout, new ReferenceCountedDisposable <RemotableDataJsonRpc>(remotableDataRpc));

                    client = new ServiceHubRemoteHostClient(workspace, primary.Logger, connectionManager, remoteHostStream);

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

                    // make sure connection is done right
                    var host = await client._rpc.InvokeWithCancellationAsync <string>(
                        nameof(IRemoteHostService.Connect), new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false);

                    client.Started();

                    return(client);
                }
                catch (ConnectionLostException ex)
                {
                    RemoteHostCrashInfoBar.ShowInfoBar(workspace, ex);

                    Shutdown(ex);

                    // dont crash VS because OOP is failed to start. we will show info bar telling users to restart
                    // but never physically crash VS.
                    return(null);
                }
                catch (SoftCrashException ex)
                {
                    Shutdown(ex);

                    // at this point, we should have shown info bar (RemoteHostCrashInfoBar.ShowInfoBar) to users
                    // returning null here will disable OOP for this VS session.
                    // * Note * this is not trying to recover the exception. but giving users to time
                    // to clean up before restart VS
                    return(null);
                }
                catch (Exception ex)
                {
                    Shutdown(ex);
                    throw;
                }

                void Shutdown(Exception ex)
                {
                    // make sure we shutdown client if initializing client has failed.
                    client?.Shutdown();

                    // translate to our own cancellation if it is raised.
                    cancellationToken.ThrowIfCancellationRequested();

                    // otherwise, report watson
                    ex.ReportServiceHubNFW("ServiceHub creation failed");
                }
            }
        }
コード例 #17
0
 internal static void InformDocumentOpen(Microsoft.CodeAnalysis.Workspace ws, Microsoft.CodeAnalysis.DocumentId analysisDocument, TextEditor editor)
 {
     ((MonoDevelopWorkspace)ws).InformDocumentOpen(analysisDocument, editor);
 }
コード例 #18
0
 public RoslynMetadataProvider()
 {
     var componentModel = ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel)) as IComponentModel;
     this.workspace = componentModel.GetService<VisualStudioWorkspace>();
 }
コード例 #19
0
 public RoslynContextActionProvider(Microsoft.CodeAnalysis.Workspace workspace)
 {
     _workspace = workspace;
 }
コード例 #20
0
 public abstract bool TryGetWorkspace(Solution solution, out Workspace workspace);