Skip to content

Commit b8fa0bc

Browse files
Make RazorProjectService operations atomic (#10322)
The work I did to make all of the public entry points on `RazorProjectService` async did so by breaking up the operations in multiple tasks. The operations themselves can't interleave because a semaphore gates just one operation at a time. However, the updates to the `ProjectSnapshotManager` made by each operation _can_ interleave with other updates to the `ProjectSnapshotManager`. This change ensures that all of the `RazorProjectService` operations are atomic WRT to the `ProjectSnapshotManger` by running each operation within a call to `ProjectSnapshotManager.UpdateAsync(...)`. In addition, I've taken a suggestion from @ryzngard to change when the miscellaneous files project is added to the `ProjectSnapshotManager` in the language server. Before this change, the misc files project would be added by the first call to `ISnapshotResolver.GetMiscellaneousProjectAsync(...)`. Now, it's added during `SnapshotResolver` initialization. This allows `GetMiscellaneousProjectAsync(...)` to become a synchronous method, which has the positive effect allowing many of the downstream callers to be synchronous as well. Ultimately, this allows all of the `RazorProjectService` operations to be implemented synchronously, which helps ensure that they are actually atomic.
2 parents d5d5f0c + 00b1ea3 commit b8fa0bc

File tree

60 files changed

+743
-695
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+743
-695
lines changed

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ await projectManager.UpdateAsync(
8787

8888
private class NoopClientNotifierService : IClientConnection, IOnInitialized
8989
{
90-
public Task OnInitializedAsync(VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken)
90+
public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken)
9191
{
9292
return Task.CompletedTask;
9393
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ClientConnection.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
8+
using Microsoft.CommonLanguageServerProtocol.Framework;
89
using Microsoft.VisualStudio.LanguageServer.Protocol;
910
using StreamJsonRpc;
1011

@@ -47,7 +48,7 @@ public async Task SendNotificationAsync(string method, CancellationToken cancell
4748
/// <summary>
4849
/// Fires when the language server is set to "Started".
4950
/// </summary>
50-
public Task OnInitializedAsync(VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken)
51+
public Task OnInitializedAsync(ILspServices services, CancellationToken cancellationToken)
5152
{
5253
_initializedCompletionSource.TrySetResult(true);
5354
return Task.CompletedTask;

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/DefaultCSharpCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ public async override Task<CodeAction> ResolveAsync(
7373
throw new ArgumentNullException(nameof(codeAction));
7474
}
7575

76-
var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(csharpParams.RazorFileIdentifier, cancellationToken).ConfigureAwait(false);
77-
if (documentContext is null)
76+
if (!_documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier, out var documentContext))
7877
{
7978
return codeAction;
8079
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CSharp/UnformattedRemappingCSharpCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ public async override Task<CodeAction> ResolveAsync(
5454

5555
cancellationToken.ThrowIfCancellationRequested();
5656

57-
var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(csharpParams.RazorFileIdentifier, cancellationToken).ConfigureAwait(false);
58-
if (documentContext is null)
57+
if (!_documentContextFactory.TryCreateForOpenDocument(csharpParams.RazorFileIdentifier, out var documentContext))
5958
{
6059
return codeAction;
6160
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Html/DefaultHtmlCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ public async override Task<CodeAction> ResolveAsync(
5555
throw new ArgumentNullException(nameof(codeAction));
5656
}
5757

58-
var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(resolveParams.RazorFileIdentifier, cancellationToken).ConfigureAwait(false);
59-
if (documentContext is null)
58+
if (!_documentContextFactory.TryCreateForOpenDocument(resolveParams.RazorFileIdentifier, out var documentContext))
6059
{
6160
return codeAction;
6261
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/AddUsingsCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public AddUsingsCodeActionResolver(IDocumentContextFactory documentContextFactor
4545
return null;
4646
}
4747

48-
var documentContext = await _documentContextFactory.TryCreateAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false);
49-
if (documentContext is null)
48+
if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext))
5049
{
5150
return null;
5251
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/CreateComponentCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ public CreateComponentCodeActionResolver(IDocumentContextFactory documentContext
4343
return null;
4444
}
4545

46-
var documentContext = await _documentContextFactory.TryCreateAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false);
47-
if (documentContext is null)
46+
if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext))
4847
{
4948
return null;
5049
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToCodeBehindCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ public ExtractToCodeBehindCodeActionResolver(
6060

6161
var path = FilePathNormalizer.Normalize(actionParams.Uri.GetAbsoluteOrUNCPath());
6262

63-
var documentContext = await _documentContextFactory.TryCreateAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false);
64-
if (documentContext is null)
63+
if (!_documentContextFactory.TryCreate(actionParams.Uri, out var documentContext))
6564
{
6665
return null;
6766
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/GenerateMethodCodeActionResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ public GenerateMethodCodeActionResolver(
7272
return null;
7373
}
7474

75-
var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(actionParams.Uri, cancellationToken).ConfigureAwait(false);
76-
if (documentContext is null)
75+
if (!_documentContextFactory.TryCreateForOpenDocument(actionParams.Uri, out var documentContext))
7776
{
7877
return null;
7978
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionItemResolver.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ private async Task<VSInternalCompletionItem> PostProcessCompletionItemAsync(
100100
}
101101

102102
var identifier = context.OriginalRequestParams.Identifier.TextDocumentIdentifier;
103-
var documentContext = await _documentContextFactory.TryCreateForOpenDocumentAsync(identifier, cancellationToken).ConfigureAwait(false);
104-
if (documentContext is null)
103+
if (!_documentContextFactory.TryCreateForOpenDocument(identifier, out var documentContext))
105104
{
106105
return resolvedCompletionItem;
107106
}

0 commit comments

Comments
 (0)