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); } }
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); } }
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; } } } }
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); } } }
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; } } }
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); } }
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; } }
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(); } }
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; } } }
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); } } }
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; } } }
protected Task <TResult> InvokeAsync <TResult>( string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken) { return(_rpc.InvokeWithCancellationAsync <TResult>(targetName, arguments?.AsArray(), cancellationToken)); }
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>()); }