未验证 提交 297aaf20 编写于 作者: H Heejae Chang 提交者: GitHub

Revert "move StreamJsonRpc to 2.x from 1.3.x (#33960)" (#34654)

This reverts commit b6285348.
上级 f78e5172
......@@ -163,7 +163,7 @@
<RoslynOptProfRunSettingsGeneratorVersion>1.0.0-beta3.19057.1</RoslynOptProfRunSettingsGeneratorVersion>
<RoslynToolsLightUpSystemRuntimeLoaderFixedVersion>4.3.0</RoslynToolsLightUpSystemRuntimeLoaderFixedVersion>
<RoslynMicrosoftVisualStudioExtensionManagerVersion>0.0.4</RoslynMicrosoftVisualStudioExtensionManagerVersion>
<StreamJsonRpcVersion>2.0.146</StreamJsonRpcVersion>
<StreamJsonRpcVersion>1.3.23</StreamJsonRpcVersion>
<SystemCollectionsImmutableVersion>1.5.0</SystemCollectionsImmutableVersion>
<SystemCommandLineExperimentalVersion>0.1.0-alpha-63729-01</SystemCommandLineExperimentalVersion>
<SystemCommandLineRenderingVersion>0.1.0-alpha-63729-01</SystemCommandLineRenderingVersion>
......
......@@ -63,7 +63,8 @@ public static async Task<RemoteHostClient> CreateAsync(Workspace workspace, bool
_inprocServices = inprocServices;
_remotableDataRpc = remotableDataRpc;
_rpc = stream.CreateStreamJsonRpc(target: this, inprocServices.Logger);
_rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target: this);
_rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
// handle disconnected situation
_rpc.Disconnected += OnRpcDisconnected;
......
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project Sdk="Microsoft.NET.Sdk">
......@@ -93,13 +93,6 @@
<!--
Exclude dependencies that are not inserted from Roslyn repo.
Note: can't use globs due to https://github.com/Microsoft/msbuild/issues/3791.
these dependency should be removed once StreamJsonRpc adds a build target for
net472 - https://github.com/dotnet/roslyn/issues/34558
<_Dependency Remove="Nerdbank.Streams"/>
<_Dependency Remove="System.IO.Pipelines"/>
<_Dependency Remove="System.ValueTuple"/>
-->
<ItemGroup>
<_Dependency Remove="@(_Dependency)" Condition="$([MSBuild]::ValueOrDefault('%(Identity)', '').StartsWith('Microsoft.VisualStudio.'))"/>
......@@ -113,9 +106,6 @@
<_Dependency Remove="Newtonsoft.Json"/>
<_Dependency Remove="stdole"/>
<_Dependency Remove="StreamJsonRpc"/>
<_Dependency Remove="Nerdbank.Streams"/>
<_Dependency Remove="System.IO.Pipelines"/>
<_Dependency Remove="System.ValueTuple"/>
<_Dependency Remove="System.Threading.Tasks.Dataflow"/>
<_Dependency Remove="VSLangProj"/>
<_Dependency Remove="VSLangProj2"/>
......
......@@ -59,7 +59,7 @@ public void TestRemoteInvocationException()
{
var mockFault = new MockFault();
var exception = new RemoteInvocationException("test", errorCode: 100, "remoteErrorData");
var exception = new RemoteInvocationException("test", "remoteCallstack", "remoteErrorCode");
mockFault.SetExtraParameters(exception, emptyCallstack: false);
Assert.Equal(exception.GetParameterString(), mockFault.Map[7]);
......@@ -70,7 +70,7 @@ public void TestRemoteInvocationExceptionNull()
{
var mockFault = new MockFault();
var exception = new RemoteInvocationException(message: null, errorCode: -1, errorData: null);
var exception = new RemoteInvocationException(message: null, remoteStack: null, remoteCode: null);
mockFault.SetExtraParameters(exception, emptyCallstack: false);
Assert.Equal(exception.GetParameterString(), mockFault.Map[7]);
......
......@@ -36,7 +36,9 @@ public JsonRpcEx(Workspace workspace, TraceSource logger, Stream stream, object
Workspace = workspace;
_logger = logger;
_rpc = stream.CreateStreamJsonRpc(target, logger);
_rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target);
_rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
_rpc.Disconnected += OnDisconnected;
}
......@@ -115,6 +117,9 @@ public async Task<T> InvokeAsync<T>(string targetName, IReadOnlyList<object> arg
private void HandleException(Exception ex, CancellationToken cancellationToken)
{
// StreamJsonRpc throws RemoteInvocationException if the call is cancelled.
// Handle this case by throwing a proper cancellation exception instead.
// See https://github.com/Microsoft/vs-streamjsonrpc/issues/67
cancellationToken.ThrowIfCancellationRequested();
LogError($"exception: {ex.ToString()}");
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using StreamJsonRpc;
namespace Microsoft.VisualStudio.LanguageServices.Remote
{
// This is a workaround for a limitation in vs-threading.
// https://github.com/dotnet/roslyn/issues/19042
internal class JsonRpcMessageHandler : HeaderDelimitedMessageHandler
{
public JsonRpcMessageHandler(Stream sendingStream, Stream receivingStream)
: base(sendingStream, receivingStream)
{
}
protected override void Dispose(bool disposing)
{
// Do not call base.Dispose. We do not want the AsyncSemaphore instances to be disposed due to a race
// condition.
if (disposing)
{
// note that this can cause double disposing of a stream if both are based on same stream.
// we can't check whether 2 are same because one of them could be wrapped stream such as bufferedstream which
// underneath points to same stream.
ReceivingStream?.Dispose();
SendingStream?.Dispose();
}
}
}
}
......@@ -146,9 +146,7 @@ protected override void Dispose(bool disposing)
protected override void Disconnected(JsonRpcDisconnectedEventArgs e)
{
// we don't expect OOP side to disconnect the connection.
// Host (VS) always initiate or disconnect the connection.
if (e.Reason != DisconnectedReason.LocallyDisposed)
if (e.Reason != DisconnectedReason.Disposed)
{
// log when this happens
LogDisconnectInfo(e, new StackTrace().ToString());
......
......@@ -98,7 +98,7 @@ public static async Task<ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace
var connectionManager = new ConnectionManager(primary, hostGroup, enableConnectionPool, maxConnection, timeout, new ReferenceCountedDisposable<RemotableDataJsonRpc>(remotableDataRpc));
client = new ServiceHubRemoteHostClient(workspace, primary.Logger, connectionManager, remoteHostStream);
client = new ServiceHubRemoteHostClient(workspace, connectionManager, remoteHostStream);
var uiCultureLCID = CultureInfo.CurrentUICulture.LCID;
var cultureLCID = CultureInfo.CurrentCulture.LCID;
......@@ -125,7 +125,6 @@ public static async Task<ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace
private ServiceHubRemoteHostClient(
Workspace workspace,
TraceSource logger,
ConnectionManager connectionManager,
Stream stream)
: base(workspace)
......@@ -134,7 +133,8 @@ public static async Task<ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace
_connectionManager = connectionManager;
_rpc = stream.CreateStreamJsonRpc(target: this, logger);
_rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target: this);
_rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
// handle disconnected situation
_rpc.Disconnected += OnRpcDisconnected;
......
......@@ -85,7 +85,7 @@ public static string GetParameterString(this Exception exception)
switch (exception)
{
case RemoteInvocationException remote:
return $"{remote.ErrorCode} {remote.StackTrace ?? exception.Message}";
return $"{remote.RemoteErrorCode} {remote.RemoteStackTrace ?? exception.Message}";
case AggregateException aggregate when aggregate.InnerException != null:
// get first exception that is not aggregated exception
return GetParameterString(aggregate.InnerException);
......
......@@ -64,7 +64,6 @@
<PackageReference Include="Microsoft.VisualStudio.Text.UI" Version="$(MicrosoftVisualStudioTextUIVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="$(MicrosoftVisualStudioTextUIWpfVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="$(MicrosoftVisualStudioValidationVersion)" />
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
</ItemGroup>
<ItemGroup>
......
......@@ -188,7 +188,7 @@ public async Task TestSessionClosed()
var session = await client.TryCreateKeepAliveSessionAsync("Test", CancellationToken.None);
// mimic unfortunate call that happens to be in the middle of communication.
var task = session.TryInvokeAsync("TestMethodAsync", arguments: null, CancellationToken.None);
var task = session.TryInvokeAsync("TestMethodAsync", SpecializedCollections.EmptyReadOnlyList<object>(), CancellationToken.None);
// make client to go away
service.Disable();
......
......@@ -50,7 +50,6 @@
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Framework" Version="$(MicrosoftVisualStudioShellFrameworkVersion)" />
<PackageReference Include="Microsoft.VisualStudio.VsInteractiveWindow" Version="$(MicrosoftVisualStudioVsInteractiveWindowVersion)" />
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
</ItemGroup>
<ItemGroup>
<PublicAPI Include="PublicAPI.Shipped.txt" />
......
......@@ -31,7 +31,6 @@
<PackageReference Include="Microsoft.VisualStudio.Editor" Version="$(MicrosoftVisualStudioEditorVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" />
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="$(MicrosoftVisualStudioComponentModelHostVersion)" />
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
</ItemGroup>
<ItemGroup>
......
......@@ -30,6 +30,9 @@
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Remote.Razor" Key="$(RazorKey)" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\VisualStudio\Core\Def\Implementation\Remote\JsonRpcMessageHandler.cs">
<Link>Shared\JsonRpcMessageHandler.cs</Link>
</Compile>
<Compile Include="..\ServiceHub\Shared\RoslynJsonConverter.cs">
<Link>Shared\RoslynJsonConverter.cs</Link>
</Compile>
......
......@@ -43,6 +43,9 @@
<Compile Include="..\..\..\VisualStudio\Core\Def\Telemetry\VSTelemetryLogger.cs">
<Link>Telemetry\VSTelemetryLogger.cs</Link>
</Compile>
<Compile Include="..\..\..\VisualStudio\Core\Def\Implementation\Remote\JsonRpcMessageHandler.cs">
<Link>Shared\JsonRpcMessageHandler.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.LiveUnitTesting.BuildManager" />
......
......@@ -18,11 +18,11 @@ internal partial class CodeAnalysisService : IRemoteAddImportFeatureService
DocumentId documentId, TextSpan span, string diagnosticId, int maxResults, bool placeSystemNamespaceFirst,
bool searchReferenceAssemblies, IList<PackageSource> packageSources, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var document = solution.GetDocument(documentId);
var service = document.GetLanguageService<IAddImportFeatureService>();
......@@ -32,7 +32,7 @@ internal partial class CodeAnalysisService : IRemoteAddImportFeatureService
var result = await service.GetFixesAsync(
document, span, diagnosticId, maxResults, placeSystemNamespaceFirst,
symbolSearchService, searchReferenceAssemblies,
packageSources.ToImmutableArray(), cancellationToken).ConfigureAwait(false);
packageSources.ToImmutableArray(), token).ConfigureAwait(false);
return (IList<AddImportFixData>)result;
}
......
......@@ -13,60 +13,60 @@ internal partial class CodeAnalysisService : IRemoteCodeLensReferencesService
{
public Task<ReferenceCount> GetReferenceCountAsync(DocumentId documentId, TextSpan textSpan, int maxResultCount, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_GetReferenceCountAsync, documentId.ProjectId.DebugName, cancellationToken))
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_GetReferenceCountAsync, documentId.ProjectId.DebugName, token))
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var syntaxNode = (await solution.GetDocument(documentId).GetSyntaxRootAsync().ConfigureAwait(false)).FindNode(textSpan);
return await CodeLensReferencesServiceFactory.Instance.GetReferenceCountAsync(solution, documentId,
syntaxNode, maxResultCount, cancellationToken).ConfigureAwait(false);
syntaxNode, maxResultCount, token).ConfigureAwait(false);
}
}, cancellationToken);
}
public Task<IEnumerable<ReferenceLocationDescriptor>> FindReferenceLocationsAsync(DocumentId documentId, TextSpan textSpan, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_FindReferenceLocationsAsync, documentId.ProjectId.DebugName, cancellationToken))
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_FindReferenceLocationsAsync, documentId.ProjectId.DebugName, token))
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var syntaxNode = (await solution.GetDocument(documentId).GetSyntaxRootAsync().ConfigureAwait(false)).FindNode(textSpan);
return await CodeLensReferencesServiceFactory.Instance.FindReferenceLocationsAsync(solution, documentId,
syntaxNode, cancellationToken).ConfigureAwait(false);
syntaxNode, token).ConfigureAwait(false);
}
}, cancellationToken);
}
public Task<IEnumerable<ReferenceMethodDescriptor>> FindReferenceMethodsAsync(DocumentId documentId, TextSpan textSpan, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_FindReferenceMethodsAsync, documentId.ProjectId.DebugName, cancellationToken))
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_FindReferenceMethodsAsync, documentId.ProjectId.DebugName, token))
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var syntaxNode = (await solution.GetDocument(documentId).GetSyntaxRootAsync().ConfigureAwait(false)).FindNode(textSpan);
return await CodeLensReferencesServiceFactory.Instance.FindReferenceMethodsAsync(solution, documentId,
syntaxNode, cancellationToken).ConfigureAwait(false);
syntaxNode, token).ConfigureAwait(false);
}
}, cancellationToken);
}
public Task<string> GetFullyQualifiedName(DocumentId documentId, TextSpan textSpan, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_GetFullyQualifiedName, documentId.ProjectId.DebugName, cancellationToken))
using (Internal.Log.Logger.LogBlock(FunctionId.CodeAnalysisService_GetFullyQualifiedName, documentId.ProjectId.DebugName, token))
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var syntaxNode = (await solution.GetDocument(documentId).GetSyntaxRootAsync().ConfigureAwait(false)).FindNode(textSpan);
return await CodeLensReferencesServiceFactory.Instance.GetFullyQualifiedName(solution, documentId,
syntaxNode, cancellationToken).ConfigureAwait(false);
syntaxNode, token).ConfigureAwait(false);
}
}, cancellationToken);
}
......
......@@ -21,18 +21,18 @@ internal partial class CodeAnalysisService : IRemoteDesignerAttributeService
/// </summary>
public Task<DesignerAttributeResult> ScanDesignerAttributesAsync(DocumentId documentId, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetDesignerAttributesAsync, documentId.DebugName, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetDesignerAttributesAsync, documentId.DebugName, token))
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var document = solution.GetDocument(documentId);
var service = document.GetLanguageService<IDesignerAttributeService>();
if (service != null)
{
// todo comment service supported
return await service.ScanDesignerAttributesAsync(document, cancellationToken).ConfigureAwait(false);
return await service.ScanDesignerAttributesAsync(document, token).ConfigureAwait(false);
}
return new DesignerAttributeResult(designerAttributeArgument: null, containsErrors: true, applicable: false);
......
......@@ -25,25 +25,25 @@ internal partial class CodeAnalysisService : IRemoteDiagnosticAnalyzerService
/// </summary>
public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string streamName, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
// if this analysis is explicitly asked by user, boost priority of this request
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, token))
using (arguments.ForcedAnalysis ? UserOperationBooster.Boost() : default)
{
try
{
// entry point for diagnostic service
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var optionSet = await RoslynServices.AssetService.GetAssetAsync<OptionSet>(arguments.OptionSetChecksum, cancellationToken).ConfigureAwait(false);
var optionSet = await RoslynServices.AssetService.GetAssetAsync<OptionSet>(arguments.OptionSetChecksum, token).ConfigureAwait(false);
var projectId = arguments.ProjectId;
var analyzers = RoslynServices.AssetService.GetGlobalAssetsOfType<AnalyzerReference>(cancellationToken);
var analyzers = RoslynServices.AssetService.GetGlobalAssetsOfType<AnalyzerReference>(token);
var result = await (new DiagnosticComputer(solution.GetProject(projectId))).GetDiagnosticsAsync(
analyzers, optionSet, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false);
analyzers, optionSet, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, token).ConfigureAwait(false);
await SerializeDiagnosticResultAsync(streamName, result, cancellationToken).ConfigureAwait(false);
await SerializeDiagnosticResultAsync(streamName, result, token).ConfigureAwait(false);
}
catch (IOException)
{
......@@ -56,11 +56,11 @@ public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string stre
public void ReportAnalyzerPerformance(List<AnalyzerPerformanceInfo> snapshot, int unitCount, CancellationToken cancellationToken)
{
RunService(() =>
RunService(token =>
{
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_ReportAnalyzerPerformance, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_ReportAnalyzerPerformance, token))
{
cancellationToken.ThrowIfCancellationRequested();
token.ThrowIfCancellationRequested();
var service = SolutionService.PrimaryWorkspace.Services.GetService<IPerformanceTrackerService>();
if (service == null)
......
......@@ -17,20 +17,20 @@ internal partial class CodeAnalysisService : IRemoteDocumentHighlights
public Task<IList<SerializableDocumentHighlights>> GetDocumentHighlightsAsync(
DocumentId documentId, int position, DocumentId[] documentIdsToSearch, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
// NOTE: In projection scenarios, we might get a set of documents to search
// that are not all the same language and might not exist in the OOP process
// (like the JS parts of a .cshtml file). Filter them out here. This will
// need to be revisited if we someday support FAR between these languages.
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var document = solution.GetDocument(documentId);
var documentsToSearch = ImmutableHashSet.CreateRange(
documentIdsToSearch.Select(solution.GetDocument).WhereNotNull());
var service = document.GetLanguageService<IDocumentHighlightsService>();
var result = await service.GetDocumentHighlightsAsync(
document, position, documentsToSearch, cancellationToken).ConfigureAwait(false);
document, position, documentsToSearch, token).ConfigureAwait(false);
return (IList<SerializableDocumentHighlights>)result.SelectAsArray(SerializableDocumentHighlights.Dehydrate);
}, cancellationToken);
......
......@@ -14,15 +14,15 @@ internal partial class CodeAnalysisService : IRemoteNavigateToSearchService
public Task<IList<SerializableNavigateToSearchResult>> SearchDocumentAsync(
DocumentId documentId, string searchPattern, string[] kinds, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var project = solution.GetDocument(documentId);
var result = await AbstractNavigateToSearchService.SearchDocumentInCurrentProcessAsync(
project, searchPattern, kinds.ToImmutableHashSet(), cancellationToken).ConfigureAwait(false);
project, searchPattern, kinds.ToImmutableHashSet(), token).ConfigureAwait(false);
return Convert(result);
}
......@@ -32,18 +32,18 @@ internal partial class CodeAnalysisService : IRemoteNavigateToSearchService
public Task<IList<SerializableNavigateToSearchResult>> SearchProjectAsync(
ProjectId projectId, DocumentId[] priorityDocumentIds, string searchPattern, string[] kinds, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var project = solution.GetProject(projectId);
var priorityDocuments = priorityDocumentIds.Select(d => solution.GetDocument(d))
.ToImmutableArray();
var result = await AbstractNavigateToSearchService.SearchProjectInCurrentProcessAsync(
project, priorityDocuments, searchPattern, kinds.ToImmutableHashSet(), cancellationToken).ConfigureAwait(false);
project, priorityDocuments, searchPattern, kinds.ToImmutableHashSet(), token).ConfigureAwait(false);
return Convert(result);
}
......
......@@ -19,14 +19,14 @@ internal partial class CodeAnalysisService : IRemoteSymbolFinder
SerializableSymbolAndProjectId symbolAndProjectIdArg, DocumentId[] documentArgs,
SerializableFindReferencesSearchOptions options, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var symbolAndProjectId = await symbolAndProjectIdArg.TryRehydrateAsync(
solution, cancellationToken).ConfigureAwait(false);
solution, token).ConfigureAwait(false);
var progressCallback = new FindReferencesProgressCallback(this, cancellationToken);
......@@ -47,23 +47,23 @@ internal partial class CodeAnalysisService : IRemoteSymbolFinder
await SymbolFinder.FindReferencesInCurrentProcessAsync(
symbolAndProjectId.Value, solution, progressCallback,
documents, options.Rehydrate(), cancellationToken).ConfigureAwait(false);
documents, options.Rehydrate(), token).ConfigureAwait(false);
}
}, cancellationToken);
}
public Task FindLiteralReferencesAsync(object value, TypeCode typeCode, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var convertedType = System.Convert.ChangeType(value, typeCode);
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var progressCallback = new FindLiteralReferencesProgressCallback(this, cancellationToken);
await SymbolFinder.FindLiteralReferencesInCurrentProcessAsync(
convertedType, solution, progressCallback, cancellationToken).ConfigureAwait(false);
convertedType, solution, progressCallback, token).ConfigureAwait(false);
}
}, cancellationToken);
}
......@@ -71,17 +71,17 @@ public Task FindLiteralReferencesAsync(object value, TypeCode typeCode, Cancella
public Task<IList<SerializableSymbolAndProjectId>> FindAllDeclarationsWithNormalQueryAsync(
ProjectId projectId, string name, SearchKind searchKind, SymbolFilter criteria, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var project = solution.GetProject(projectId);
using (var query = SearchQuery.Create(name, searchKind))
{
var result = await DeclarationFinder.FindAllDeclarationsWithNormalQueryInCurrentProcessAsync(
project, query, criteria, cancellationToken).ConfigureAwait(false);
project, query, criteria, token).ConfigureAwait(false);
return (IList<SerializableSymbolAndProjectId>)result.SelectAsArray(SerializableSymbolAndProjectId.Dehydrate);
}
......@@ -92,13 +92,13 @@ public Task FindLiteralReferencesAsync(object value, TypeCode typeCode, Cancella
public Task<IList<SerializableSymbolAndProjectId>> FindSolutionSourceDeclarationsWithNormalQueryAsync(
string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var result = await DeclarationFinder.FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync(
solution, name, ignoreCase, criteria, cancellationToken).ConfigureAwait(false);
solution, name, ignoreCase, criteria, token).ConfigureAwait(false);
return (IList<SerializableSymbolAndProjectId>)result.SelectAsArray(SerializableSymbolAndProjectId.Dehydrate);
}
......@@ -108,15 +108,15 @@ public Task FindLiteralReferencesAsync(object value, TypeCode typeCode, Cancella
public Task<IList<SerializableSymbolAndProjectId>> FindProjectSourceDeclarationsWithNormalQueryAsync(
ProjectId projectId, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var project = solution.GetProject(projectId);
var result = await DeclarationFinder.FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync(
project, name, ignoreCase, criteria, cancellationToken).ConfigureAwait(false);
project, name, ignoreCase, criteria, token).ConfigureAwait(false);
return (IList<SerializableSymbolAndProjectId>)result.SelectAsArray(SerializableSymbolAndProjectId.Dehydrate);
}
......@@ -126,14 +126,14 @@ public Task FindLiteralReferencesAsync(object value, TypeCode typeCode, Cancella
public Task<IList<SerializableSymbolAndProjectId>> FindSolutionSourceDeclarationsWithPatternAsync(
string pattern, SymbolFilter criteria, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var result = await DeclarationFinder.FindSourceDeclarationsWithPatternInCurrentProcessAsync(
solution, pattern, criteria, cancellationToken).ConfigureAwait(false);
solution, pattern, criteria, token).ConfigureAwait(false);
return (IList<SerializableSymbolAndProjectId>)result.SelectAsArray(SerializableSymbolAndProjectId.Dehydrate);
}
......@@ -143,15 +143,15 @@ public Task FindLiteralReferencesAsync(object value, TypeCode typeCode, Cancella
public Task<IList<SerializableSymbolAndProjectId>> FindProjectSourceDeclarationsWithPatternAsync(
ProjectId projectId, string pattern, SymbolFilter criteria, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (UserOperationBooster.Boost())
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var project = solution.GetProject(projectId);
var result = await DeclarationFinder.FindSourceDeclarationsWithPatternInCurrentProcessAsync(
project, pattern, criteria, cancellationToken).ConfigureAwait(false);
project, pattern, criteria, token).ConfigureAwait(false);
return (IList<SerializableSymbolAndProjectId>)result.SelectAsArray(SerializableSymbolAndProjectId.Dehydrate);
}
......
......@@ -22,18 +22,18 @@ internal partial class CodeAnalysisService : IRemoteTodoCommentService
/// </summary>
public Task<IList<TodoComment>> GetTodoCommentsAsync(DocumentId documentId, IList<TodoCommentDescriptor> tokens, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetTodoCommentsAsync, documentId.DebugName, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetTodoCommentsAsync, documentId.DebugName, token))
{
var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
var solution = await GetSolutionAsync(token).ConfigureAwait(false);
var document = solution.GetDocument(documentId);
var service = document.GetLanguageService<ITodoCommentService>();
if (service != null)
{
// todo comment service supported
return await service.GetTodoCommentsAsync(document, tokens, cancellationToken).ConfigureAwait(false);
return await service.GetTodoCommentsAsync(document, tokens, token).ConfigureAwait(false);
}
return SpecializedCollections.EmptyList<TodoComment>();
......
......@@ -23,7 +23,6 @@
using Microsoft.VisualStudio.LanguageServices.Telemetry;
using Microsoft.VisualStudio.Telemetry;
using Roslyn.Utilities;
using StreamJsonRpc;
using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger;
namespace Microsoft.CodeAnalysis.Remote
......@@ -37,7 +36,6 @@ namespace Microsoft.CodeAnalysis.Remote
internal partial class RemoteHostService : ServiceHubServiceBase, IRemoteHostService
{
private readonly static TimeSpan s_reportInterval = TimeSpan.FromMinutes(2);
private readonly CancellationTokenSource _shutdownCancellationSource;
// it is saved here more on debugging purpose.
private static Func<FunctionId, bool> s_logChecker = _ => false;
......@@ -58,17 +56,15 @@ static RemoteHostService()
public RemoteHostService(Stream stream, IServiceProvider serviceProvider) :
base(serviceProvider, stream)
{
_shutdownCancellationSource = new CancellationTokenSource();
// this service provide a way for client to make sure remote host is alive
StartService();
}
public string Connect(string host, int uiCultureLCID, int cultureLCID, string serializedSession, CancellationToken cancellationToken)
{
return RunService(() =>
return RunService(token =>
{
cancellationToken.ThrowIfCancellationRequested();
token.ThrowIfCancellationRequested();
_primaryInstance = InstanceId;
......@@ -97,16 +93,9 @@ public string Connect(string host, int uiCultureLCID, int cultureLCID, string se
}, cancellationToken);
}
protected override void OnDisconnected(JsonRpcDisconnectedEventArgs e)
{
_shutdownCancellationSource.Cancel();
base.OnDisconnected(e);
}
public void UpdateSolutionStorageLocation(SolutionId solutionId, string storageLocation, CancellationToken cancellationToken)
{
RunService(() =>
RunService(_ =>
{
var persistentStorageService = GetPersistentStorageService();
persistentStorageService.UpdateStorageLocation(solutionId, storageLocation);
......@@ -115,7 +104,7 @@ public void UpdateSolutionStorageLocation(SolutionId solutionId, string storageL
public void OnGlobalOperationStarted(string unused)
{
RunService(() =>
RunService(_ =>
{
var globalOperationNotificationService = GetGlobalOperationNotificationService();
globalOperationNotificationService?.OnStarted();
......@@ -124,7 +113,7 @@ public void OnGlobalOperationStarted(string unused)
public void OnGlobalOperationStopped(IReadOnlyList<string> operations, bool cancelled)
{
RunService(() =>
RunService(_ =>
{
var globalOperationNotificationService = GetGlobalOperationNotificationService();
globalOperationNotificationService?.OnStopped(operations, cancelled);
......@@ -133,14 +122,14 @@ public void OnGlobalOperationStopped(IReadOnlyList<string> operations, bool canc
public void SetLoggingFunctionIds(List<string> loggerTypes, List<string> functionIds, CancellationToken cancellationToken)
{
RunService(() =>
RunService(token =>
{
var functionIdType = typeof(FunctionId);
var set = new HashSet<FunctionId>();
foreach (var functionIdString in functionIds)
{
cancellationToken.ThrowIfCancellationRequested();
token.ThrowIfCancellationRequested();
try
{
......@@ -210,7 +199,7 @@ private void SetGlobalContext(int uiCultureLCID, int cultureLCID, string seriali
if (diagnosticAnalyzerPerformanceTracker != null)
{
var globalOperationNotificationService = SolutionService.PrimaryWorkspace.Services.GetService<IGlobalOperationNotificationService>();
_performanceReporter = new PerformanceReporter(Logger, diagnosticAnalyzerPerformanceTracker, globalOperationNotificationService, s_reportInterval, _shutdownCancellationSource.Token);
_performanceReporter = new PerformanceReporter(Logger, diagnosticAnalyzerPerformanceTracker, globalOperationNotificationService, s_reportInterval, ShutdownCancellationToken);
}
}
......@@ -295,23 +284,23 @@ private static void SetNativeDllSearchDirectories()
public Task SynchronizePrimaryWorkspaceAsync(Checksum checksum, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizePrimaryWorkspaceAsync, Checksum.GetChecksumLogInfo, checksum, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizePrimaryWorkspaceAsync, Checksum.GetChecksumLogInfo, checksum, token))
{
var solutionController = (ISolutionController)RoslynServices.SolutionService;
await solutionController.UpdatePrimaryWorkspaceAsync(checksum, cancellationToken).ConfigureAwait(false);
await solutionController.UpdatePrimaryWorkspaceAsync(checksum, token).ConfigureAwait(false);
}
}, cancellationToken);
}
public Task SynchronizeGlobalAssetsAsync(Checksum[] checksums, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeGlobalAssetsAsync, Checksum.GetChecksumsLogInfo, checksums, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeGlobalAssetsAsync, Checksum.GetChecksumsLogInfo, checksums, token))
{
var assets = await RoslynServices.AssetService.GetAssetsAsync<object>(checksums, cancellationToken).ConfigureAwait(false);
var assets = await RoslynServices.AssetService.GetAssetsAsync<object>(checksums, token).ConfigureAwait(false);
foreach (var asset in assets)
{
......@@ -323,9 +312,9 @@ public Task SynchronizeGlobalAssetsAsync(Checksum[] checksums, CancellationToken
public Task SynchronizeTextAsync(DocumentId documentId, Checksum baseTextChecksum, IEnumerable<TextChange> textChanges, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeTextAsync, Checksum.GetChecksumLogInfo, baseTextChecksum, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeTextAsync, Checksum.GetChecksumLogInfo, baseTextChecksum, token))
{
var service = SolutionService.PrimaryWorkspace.Services.GetService<ISerializerService>();
if (service == null)
......@@ -342,7 +331,7 @@ public Task SynchronizeTextAsync(DocumentId documentId, Checksum baseTextChecksu
}
var newText = new WrappedText(text.WithChanges(textChanges));
var newChecksum = service.CreateChecksum(newText, cancellationToken);
var newChecksum = service.CreateChecksum(newText, token);
// save new text in the cache so that when asked, the data is most likely already there
//
......@@ -383,7 +372,7 @@ async Task<SourceText> TryGetSourceTextAsync()
return null;
}
return await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
return await document.GetTextAsync(token).ConfigureAwait(false);
}
}, cancellationToken);
}
......
......@@ -26,7 +26,7 @@ public RemoteSymbolSearchUpdateEngine(Stream stream, IServiceProvider servicePro
public Task UpdateContinuouslyAsync(string sourceName, string localSettingsDirectory)
{
return RunServiceAsync(() =>
return RunServiceAsync(_ =>
{
return _updateEngine.UpdateContinuouslyAsync(sourceName, localSettingsDirectory);
}, CancellationToken.None);
......@@ -34,10 +34,10 @@ public Task UpdateContinuouslyAsync(string sourceName, string localSettingsDirec
public Task<IList<PackageWithTypeResult>> FindPackagesWithTypeAsync(string source, string name, int arity, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
var results = await _updateEngine.FindPackagesWithTypeAsync(
source, name, arity, cancellationToken).ConfigureAwait(false);
source, name, arity, token).ConfigureAwait(false);
return (IList<PackageWithTypeResult>)results;
}, cancellationToken);
......@@ -45,10 +45,10 @@ public Task<IList<PackageWithTypeResult>> FindPackagesWithTypeAsync(string sourc
public Task<IList<PackageWithAssemblyResult>> FindPackagesWithAssemblyAsync(string source, string assemblyName, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
var results = await _updateEngine.FindPackagesWithAssemblyAsync(
source, assemblyName, cancellationToken).ConfigureAwait(false);
source, assemblyName, token).ConfigureAwait(false);
return (IList<PackageWithAssemblyResult>)results;
}, cancellationToken);
......@@ -56,10 +56,10 @@ public Task<IList<PackageWithAssemblyResult>> FindPackagesWithAssemblyAsync(stri
public Task<IList<ReferenceAssemblyWithTypeResult>> FindReferenceAssembliesWithTypeAsync(string name, int arity, CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
return RunServiceAsync(async token =>
{
var results = await _updateEngine.FindReferenceAssembliesWithTypeAsync(
name, arity, cancellationToken).ConfigureAwait(false);
name, arity, token).ConfigureAwait(false);
return (IList<ReferenceAssemblyWithTypeResult>)results;
}, cancellationToken);
......
......@@ -30,20 +30,20 @@ public JsonRpcAssetSource(SnapshotService owner) : base(owner.AssetStorage)
_owner = owner;
}
public override async Task<IList<(Checksum, object)>> RequestAssetsAsync(int scopeId, ISet<Checksum> checksums, ISerializerService serializerService, CancellationToken cancellationToken)
public override async Task<IList<(Checksum, object)>> RequestAssetsAsync(int scopeId, ISet<Checksum> checksums, ISerializerService serializerService, CancellationToken callerCancellation)
{
using (RoslynLogger.LogBlock(FunctionId.SnapshotService_RequestAssetAsync, GetRequestLogInfo, scopeId, checksums, cancellationToken))
using (RoslynLogger.LogBlock(FunctionId.SnapshotService_RequestAssetAsync, GetRequestLogInfo, scopeId, checksums, callerCancellation))
{
try
{
return await _owner.RunServiceAsync(() =>
return await _owner.RunServiceAsync(cancellationToken =>
{
return _owner.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
new object[] { scopeId, checksums.ToArray() },
(s, c) => ReadAssets(s, scopeId, checksums, serializerService, c), cancellationToken);
}, cancellationToken).ConfigureAwait(false);
}, callerCancellation).ConfigureAwait(false);
}
catch (Exception ex) when (ReportUnlessCanceled(ex, cancellationToken))
catch (Exception ex) when (ReportUnlessCanceled(ex, callerCancellation))
{
throw ExceptionUtilities.Unreachable;
}
......
......@@ -2,14 +2,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.VisualStudio.Telemetry;
using Newtonsoft.Json;
using Roslyn.Utilities;
using StreamJsonRpc;
......@@ -17,24 +15,6 @@ namespace Microsoft.CodeAnalysis.Remote
{
internal static partial class Extensions
{
public static JsonRpc CreateStreamJsonRpc(
this Stream stream,
object target,
TraceSource logger,
IEnumerable<JsonConverter> jsonConverters = null)
{
jsonConverters = jsonConverters ?? SpecializedCollections.EmptyEnumerable<JsonConverter>();
var jsonFormatter = new JsonMessageFormatter();
jsonFormatter.JsonSerializer.Converters.AddRange(jsonConverters.Concat(AggregateJsonConverter.Instance));
return new JsonRpc(new HeaderDelimitedMessageHandler(stream, jsonFormatter), target)
{
CancelLocallyInvokedMethodsWhenConnectionIsClosed = true,
TraceSource = logger
};
}
public static async Task InvokeAsync(
this JsonRpc rpc, string targetName, IReadOnlyList<object> arguments,
Func<Stream, CancellationToken, Task> funcWithDirectStreamAsync, CancellationToken cancellationToken)
......
......@@ -8,7 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Execution;
using Newtonsoft.Json;
using Microsoft.VisualStudio.LanguageServices.Remote;
using Roslyn.Utilities;
using StreamJsonRpc;
......@@ -20,12 +20,14 @@ internal abstract class ServiceHubServiceBase : IDisposable
{
private static int s_instanceId;
private readonly CancellationTokenSource _shutdownCancellationSource;
private readonly JsonRpc _rpc;
protected readonly int InstanceId;
protected readonly TraceSource Logger;
protected readonly AssetStorage AssetStorage;
protected readonly CancellationToken ShutdownCancellationToken;
[Obsolete("don't use RPC directly but use it through StartService and InvokeAsync", error: true)]
protected readonly JsonRpc Rpc;
......@@ -47,12 +49,7 @@ internal abstract class ServiceHubServiceBase : IDisposable
private bool _disposed;
protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream) :
this(serviceProvider, stream, SpecializedCollections.EmptyEnumerable<JsonConverter>())
{
}
protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream, IEnumerable<JsonConverter> jsonConverters)
protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream)
{
InstanceId = Interlocked.Add(ref s_instanceId, 1);
_disposed = false;
......@@ -63,12 +60,14 @@ protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream,
Logger = (TraceSource)serviceProvider.GetService(typeof(TraceSource));
Logger.TraceInformation($"{DebugInstanceString} Service instance created");
_shutdownCancellationSource = new CancellationTokenSource();
ShutdownCancellationToken = _shutdownCancellationSource.Token;
// due to this issue - https://github.com/dotnet/roslyn/issues/16900#issuecomment-277378950
// all sub type must explicitly start JsonRpc once everything is
// setup.
// we also wires given json converters when creating JsonRpc so that razor or SBD can register
// their own converter when they create their own service
_rpc = stream.CreateStreamJsonRpc(target: this, Logger, jsonConverters);
// setup
_rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), this);
_rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
_rpc.Disconnected += OnRpcDisconnected;
// we do this since we want to mark Rpc as obsolete but want to set its value for
......@@ -114,7 +113,7 @@ protected void StartService()
protected Task InvokeAsync(string targetName, CancellationToken cancellationToken)
{
return InvokeAsync(targetName, arguments: null, cancellationToken);
return InvokeAsync(targetName, SpecializedCollections.EmptyReadOnlyList<object>(), cancellationToken);
}
protected Task InvokeAsync(
......@@ -165,6 +164,7 @@ public void Dispose()
_disposed = true;
_rpc.Dispose();
_shutdownCancellationSource.Dispose();
Dispose(disposing: true);
......@@ -184,12 +184,11 @@ protected void Log(TraceEventType errorType, string message)
private void OnRpcDisconnected(object sender, JsonRpcDisconnectedEventArgs e)
{
// raise cancellation
_shutdownCancellationSource.Cancel();
OnDisconnected(e);
// either service naturally went away since nobody is using
// or the other side closed the connection such as closing VS
if (e.Reason != DisconnectedReason.LocallyDisposed &&
e.Reason != DisconnectedReason.RemotePartyTerminated)
if (e.Reason != DisconnectedReason.Disposed)
{
// we no longer close connection forcefully. so connection shouldn't go away
// in normal situation. if it happens, log why it did in more detail.
......@@ -207,119 +206,86 @@ private static Task<Solution> GetSolutionAsync(RoslynServices roslynService, Pin
return solutionController.GetSolutionAsync(solutionInfo.SolutionChecksum, solutionInfo.FromPrimaryBranch, cancellationToken);
}
protected async Task<T> RunServiceAsync<T>(Func<Task<T>> callAsync, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
{
return await callAsync().ConfigureAwait(false);
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
}
}
protected async Task RunServiceAsync(Func<Task> callAsync, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
{
await callAsync().ConfigureAwait(false);
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
}
}
protected T RunService<T>(Func<T> call, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
{
return call();
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
}
}
protected void RunService(Action call, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
{
call();
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
}
}
[Obsolete("Use one with no CancellationToken given. underlying issue has been addressed", error: true)]
protected async Task<T> RunServiceAsync<T>(Func<CancellationToken, Task<T>> callAsync, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
// merge given cancellation token with shutdown cancellation token. it looks like if cancellation and disconnection happens
// almost same time, we might not get cancellation message back from stream json rpc and get disconnected
// https://github.com/Microsoft/vs-streamjsonrpc/issues/64
using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ShutdownCancellationToken))
{
return await callAsync(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
try
{
return await callAsync(mergedCancellation.Token).ConfigureAwait(false);
}
catch (Exception ex) when (LogUnlessCanceled(ex, mergedCancellation.Token))
{
// never reach
throw ExceptionUtilities.Unreachable;
}
}
}
[Obsolete("Use one with no CancellationToken given. underlying issue has been addressed", error: true)]
protected async Task RunServiceAsync(Func<CancellationToken, Task> callAsync, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
{
await callAsync(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
// merge given cancellation token with shutdown cancellation token. it looks like if cancellation and disconnection happens
// almost same time, we might not get cancellation message back from stream json rpc and get disconnected
// https://github.com/Microsoft/vs-streamjsonrpc/issues/64
using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ShutdownCancellationToken))
{
throw ExceptionUtilities.Unreachable;
try
{
await callAsync(mergedCancellation.Token).ConfigureAwait(false);
}
catch (Exception ex) when (LogUnlessCanceled(ex, mergedCancellation.Token))
{
// never reach
return;
}
}
}
[Obsolete("Use one with no CancellationToken given. underlying issue has been addressed", error: true)]
protected T RunService<T>(Func<CancellationToken, T> call, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
// merge given cancellation token with shutdown cancellation token. it looks like if cancellation and disconnection happens
// almost same time, we might not get cancellation message back from stream json rpc and get disconnected
// https://github.com/Microsoft/vs-streamjsonrpc/issues/64
using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ShutdownCancellationToken))
{
return call(cancellationToken);
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
{
throw ExceptionUtilities.Unreachable;
try
{
return call(mergedCancellation.Token);
}
catch (Exception ex) when (LogUnlessCanceled(ex, mergedCancellation.Token))
{
// never reach
return default;
}
}
}
[Obsolete("Use one with no CancellationToken given. underlying issue has been addressed", error: true)]
protected void RunService(Action<CancellationToken> call, CancellationToken cancellationToken)
{
AssetStorage.UpdateLastActivityTime();
try
{
call(cancellationToken);
}
catch (Exception ex) when (LogUnlessCanceled(ex, cancellationToken))
// merge given cancellation token with shutdown cancellation token. it looks like if cancellation and disconnection happens
// almost same time, we might not get cancellation message back from stream json rpc and get disconnected
// https://github.com/Microsoft/vs-streamjsonrpc/issues/64
using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ShutdownCancellationToken))
{
throw ExceptionUtilities.Unreachable;
try
{
call(mergedCancellation.Token);
}
catch (Exception ex) when (LogUnlessCanceled(ex, mergedCancellation.Token))
{
// never reach
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册