Пример #1
0
        public async Task InvokeAsync(
            string targetName,
            IReadOnlyList <object?> arguments,
            CancellationToken cancellationToken
            )
        {
            Contract.ThrowIfFalse(_startedListening);

            // if this end-point is already disconnected do not log more errors:
            var logError = _disconnectedReason == null;

            try
            {
                await _rpc.InvokeWithCancellationAsync(targetName, arguments, cancellationToken)
                .ConfigureAwait(false);
            }
            catch (Exception ex) when(!logError || ReportUnlessCanceled(ex, cancellationToken))
            {
                // Remote call may fail with different exception even when our cancellation token is signaled
                // (e.g. on shutdown if the connection is dropped):
                cancellationToken.ThrowIfCancellationRequested();

                throw CreateSoftCrashException(ex, cancellationToken);
            }
        }
Пример #2
0
        public async Task InvokeAsync(string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _rpc.InvokeWithCancellationAsync(targetName, arguments, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex) when(ReportUnlessCanceled(ex, cancellationToken))
            {
                HandleException(ex, cancellationToken);
            }
        }
Пример #3
0
        public async Task InvokeAsync(string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _rpc.InvokeWithCancellationAsync(targetName, arguments, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex) when(ReportUnlessCanceled(ex, cancellationToken))
            {
                // if any exception is thrown unrelated to cancellation, then we will rethrow the exception
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
        static async Task MainAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("Connecting to web socket...");
            using (var socket = new ClientWebSocket())
            {
                await socket.ConnectAsync(new Uri("wss://localhost:44392/socket"), cancellationToken);

                Console.WriteLine("Connected to web socket. Establishing JSON-RPC protocol...");
                using (var jsonRpc = new JsonRpc(new WebSocketMessageHandler(socket)))
                {
                    try
                    {
                        jsonRpc.AddLocalRpcMethod("Tick", new Action <int>(tick => Console.WriteLine($"Tick {tick}!")));
                        jsonRpc.StartListening();
                        Console.WriteLine("JSON-RPC protocol over web socket established.");
                        int result = await jsonRpc.InvokeWithCancellationAsync <int>("Add", new object[] { 1, 2 }, cancellationToken);

                        Console.WriteLine($"JSON-RPC server says 1 + 2 = {result}");

                        // Request notifications from the server.
                        await jsonRpc.NotifyAsync("SendTicksAsync");

                        await jsonRpc.Completion.WithCancellation(cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                        // Closing is initiated by Ctrl+C on the client.
                        // Close the web socket gracefully -- before JsonRpc is disposed to avoid the socket going into an aborted state.
                        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client closing", CancellationToken.None);

                        throw;
                    }
                }
            }
        }
Пример #5
0
        async Task RunScriptWithRemotePowerShellConsoleHost(
            string method,
            object message,
            INuGetProjectContext nuGetProjectContext,
            bool throwOnFailure,
            CancellationToken token)
        {
            try {
                var result = await rpc.InvokeWithCancellationAsync <RunScriptResult> (method, new[] { message }, token);

                if (!result.Success)
                {
                    throw new ApplicationException(result.ErrorMessage);
                }
            } catch (Exception ex) {
                if (throwOnFailure)
                {
                    throw;
                }
                else
                {
                    nuGetProjectContext.Log(MessageLevel.Warning, ex.Message);
                }
            }
        }
Пример #6
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IReadOnlyList <object> arguments,
            Action <Stream, CancellationToken> actionWithDirectStream, CancellationToken cancellationToken)
        {
            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeWithCancellationAsync(targetName, arguments.Concat(stream.Name).ToArray(), mergedCancellation.Token);

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        actionWithDirectStream(stream, mergedCancellation.Token);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, mergedCancellation.Token, cancellationToken))
                    {
                        // important to use cancelationToken here rather than mergedCancellationToken.
                        // there is a slight delay when merged cancellation token will be notified once cancellation token
                        // is raised, it can cause one to be in cancelled mode and the other is not. here, one we
                        // actually care is the cancellation token given in, not the merged cancellation token.
                        cancellationToken.ThrowIfCancellationRequested();
                        throw;
                    }
                }
        }
Пример #7
0
        public async Task InvokeAsync(string targetName, IReadOnlyList <object?> arguments, CancellationToken cancellationToken)
        {
            Contract.ThrowIfFalse(_startedListening);

            try
            {
                await _rpc.InvokeWithCancellationAsync(targetName, arguments?.AsArray(), cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex) when(ReportUnlessCanceled(ex, cancellationToken))
            {
                // Remote call may fail with different exception even when our cancellation token is signaled
                // (e.g. on shutdown if the connection is dropped):
                cancellationToken.ThrowIfCancellationRequested();

                throw CreateSoftCrashException(ex, cancellationToken);
            }
        }
Пример #8
0
        public async Task InvokeAsync(string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _rpc.InvokeWithCancellationAsync(targetName, arguments, cancellationToken).ConfigureAwait(false);
            }
            catch
            {
                // any exception can be thrown from StreamJsonRpc if JsonRpc is disposed in the middle of read/write.
                // until we move to newly added cancellation support in JsonRpc, we will catch exception and translate to
                // cancellation exception here. if any exception is thrown unrelated to cancellation, then we will rethrow
                // the exception
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
Пример #9
0
        public async Task InvokeAsync(string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _rpc.InvokeWithCancellationAsync(targetName, arguments, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex) when(ReportUnlessCanceled(ex, cancellationToken))
            {
                // any exception can be thrown from StreamJsonRpc if JsonRpc is disposed in the middle of read/write.
                // until we move to newly added cancellation support in JsonRpc, we will catch exception and translate to
                // cancellation exception here. if any exception is thrown unrelated to cancellation, then we will rethrow
                // the exception
                cancellationToken.ThrowIfCancellationRequested();

                // this is to make us not crash. we should remove this once we figure out
                // what is causing this
                ThrowOwnCancellationToken();
            }
        }
Пример #10
0
        public static async Task <T> InvokeAsync <T>(
            this JsonRpc rpc, string targetName, IReadOnlyList <object> arguments,
            Func <Stream, CancellationToken, Task <T> > funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            Task task = null;

            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request to asset source
                        task = rpc.InvokeWithCancellationAsync(targetName, arguments.Concat(stream.Name).ToArray(), cancellationToken);

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        var result = await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);

                        return(result);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, mergedCancellation.Token, cancellationToken))
                    {
                        // important to use cancelationToken here rather than mergedCancellationToken.
                        // there is a slight delay when merged cancellation token will be notified once cancellation token
                        // is raised, it can cause one to be in cancelled mode and the other is not. here, one we
                        // actually care is the cancellation token given in, not the merged cancellation token.
                        cancellationToken.ThrowIfCancellationRequested();

                        // record reason why task got aborted. use NFW here since we don't want to
                        // crash VS on explicitly killing OOP.
                        task.Exception.ReportServiceHubNFW("JsonRpc Invoke Failed");

                        throw;
                    }
                }
        }
Пример #11
0
 private async Task RpcInvokeAsync(string targetName, params object[] arguments)
 {
     // handle exception gracefully. don't crash VS due to this.
     // especially on shutdown time. because of pending async BG work such as
     // OnGlobalOperationStarted and more, we can get into a situation where either
     // we are in the middle of call when we are disconnected, or we runs
     // after shutdown.
     try
     {
         await _rpc.InvokeWithCancellationAsync(targetName, arguments?.AsArray(), _shutdownCancellationTokenSource.Token).ConfigureAwait(false);
     }
     catch (Exception ex) when(ReportUnlessCanceled(ex))
     {
         if (!_shutdownCancellationTokenSource.IsCancellationRequested)
         {
             RemoteHostCrashInfoBar.ShowInfoBar(Workspace, ex);
         }
     }
 }
Пример #12
0
        static async Task MainAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("Connecting to web socket...");
            using (var socket = new ClientWebSocket())
            {
                await socket.ConnectAsync(new Uri("ws://localhost:7919"), cancellationToken);

                Console.WriteLine("Connected to web socket. Establishing JSON-RPC protocol...");

                // to work with 'vscode-jsonrpc' server, need to use this handler
                // refer to: https://github.com/microsoft/vs-streamjsonrpc/blob/main/doc/extensibility.md
                var handler = new HeaderDelimitedMessageHandler(socket.AsStream());
                var jsonRpc = new JsonRpc(handler);
                try
                {
                    jsonRpc.StartListening();
                    Console.WriteLine("JSON-RPC protocol over web socket established.");

                    await jsonRpc.NotifyAsync("testNotification", "Hello from dotnet");

                    object[] param  = { 1, 2 };
                    var      result = await jsonRpc.InvokeWithCancellationAsync <int>("Add", param, cancellationToken);

                    Console.WriteLine($"JSON-RPC server says 1 + 2 = {result}");

                    await jsonRpc.Completion.WithCancellation(cancellationToken);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client Closing", CancellationToken.None);

                    throw;
                }
            }
        }
Пример #13
0
 protected Task <TResult> InvokeAsync <TResult>(
     string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken)
 {
     return(_rpc.InvokeWithCancellationAsync <TResult>(targetName, arguments?.AsArray(), cancellationToken));
 }
Пример #14
0
        public async Task <List <QuickFix> > QueryAsync(string filter, int maxResults, TimeSpan timeout, bool exactMatch, CodeSearchQueryType searchType)
        {
            if (_jsonRpc == null)
            {
                return(new List <QuickFix>());
            }

            List <QuickFix> results = null;
            string          searchTypeString;

            switch (searchType)
            {
            case CodeSearchQueryType.FindDefinitions:
                searchTypeString = $"def:{filter}";
                break;

            case CodeSearchQueryType.FindReferences:
                searchTypeString = $"{filter}";     // Do not use ref: prefix because it misses too many things
                break;

            default:
                throw new InvalidOperationException($"Unknown search type {searchType}");
            }

            string cacheKey = $"{searchTypeString}{(exactMatch ? string.Empty : "*")}";

            if (_queryResultsCache.TryGetValue(cacheKey, out object cachedValue))
            {
                var cachedResults = (List <QuickFix>)cachedValue;
                _logger.LogDebug($"FastCodeNav: Reusing cached value for '{cacheKey}' that contains {cachedResults.Count()} result(s)");
                return(cachedResults);
            }

            try
            {
                _logger.LogDebug($"FastCodeNav: Searching for '{cacheKey}'");
                using (var ct = new CancellationTokenSource(timeout))
                {
                    Stopwatch     sw       = Stopwatch.StartNew();
                    SearchResults response = await _jsonRpc.InvokeWithCancellationAsync <SearchResults>("SearchCodeAsync",
                                                                                                        new[] { new SearchRequest
                                                                                                                {
                                                                                                                    Filter         = filter,
                                                                                                                    MaxResults     = maxResults,
                                                                                                                    Timeout        = timeout,
                                                                                                                    ExactMatch     = exactMatch,
                                                                                                                    FindReferences = searchType == CodeSearchQueryType.FindReferences
                                                                                                                } }, ct.Token);

                    _logger.LogDebug($"FastCodeNav: search for '{cacheKey}' completed in {sw.Elapsed.TotalSeconds:F2} seconds and contains {response.Results.Count()} result(s)");

                    if (response != null)
                    {
                        results = new List <QuickFix>();
                        foreach (SearchResult searchResult in response.Results)
                        {
                            _logger.LogTrace($"FastCodeNav: result for '{cacheKey}': ({searchResult.Line},{searchResult.Column},{searchResult.EndLine},{searchResult.EndColumn}) {searchResult.FileName} |{searchResult.Text}|");
                            results.Add(new QuickFix
                            {
                                FileName  = searchResult.FileName,
                                Text      = searchResult.Text,
                                Line      = searchResult.Line,
                                Column    = searchResult.Column,
                                EndLine   = searchResult.EndLine,
                                EndColumn = searchResult.EndColumn,
                            });
                        }

                        _queryResultsCache.Set(cacheKey, results, TimeSpan.FromMinutes(5));
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Failed to search for '{cacheKey}'");
            }

            return(results ?? new List <QuickFix>());
        }