Skip to content

Commit 2a185e5

Browse files
Remove ProjectSnapshotManagerDispatcher from RazorFileChangeDetector (#10278)
This change removes usage of `ProjectSnapshotManagerDispatcher` from `RazorFileChangeDetector`. In order to achieve that, I've refactored `RazorFileChangeDetector` to use an `AsyncBatchingWorkQueue` rather than the existing complex strategy of tracking a dictionary of "pending notifications" with delayed tasks. However, the `ProcessBatchAsync` is a bit trickier than others I've implemented. To reduce churn on the `RazorProjectService`, `RazorFileChangeDetector` does extra work to try and avoid elide adds/remove pairs for the same file. This makes the `ProcessBatchAsync` more complex because we need to pass through the items in the batch once to find add/remove pairs and make note of the changes we should skip. Then, we make a second pass and notify the listeners of changes, taking care to step over skipped changes we noted in the first pass. I hope the comments there clarify the new strategy. The behavior should be approximately the same.
2 parents 006e536 + 2381352 commit 2a185e5

File tree

9 files changed

+289
-351
lines changed

9 files changed

+289
-351
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4+
using System.Threading;
5+
using System.Threading.Tasks;
46
using Microsoft.AspNetCore.Razor.LanguageServer.Common;
57

68
namespace Microsoft.AspNetCore.Razor.LanguageServer;
79

810
internal interface IRazorFileChangeListener
911
{
10-
void RazorFileChanged(string filePath, RazorFileChangeKind kind);
12+
Task RazorFileChangedAsync(string filePath, RazorFileChangeKind kind, CancellationToken cancellationToken);
1113
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT license. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Razor.LanguageServer.Common;
5+
using System.Threading.Tasks;
6+
using System;
7+
8+
namespace Microsoft.AspNetCore.Razor.LanguageServer;
9+
10+
internal partial class RazorFileChangeDetector
11+
{
12+
internal TestAccessor GetTestAccessor() => new(this);
13+
14+
internal sealed class TestAccessor(RazorFileChangeDetector instance)
15+
{
16+
public void AddWork(string filePath, RazorFileChangeKind kind)
17+
{
18+
if (kind is not (RazorFileChangeKind.Added or RazorFileChangeKind.Removed))
19+
{
20+
throw new ArgumentException("Only adds and removes are allowed", nameof(kind));
21+
}
22+
23+
instance._workQueue.AddWork((filePath, kind));
24+
}
25+
26+
public void AddWork(params (string filePath, RazorFileChangeKind kind)[] items)
27+
{
28+
foreach (var (filePath, kind) in items)
29+
{
30+
if (kind is not (RazorFileChangeKind.Added or RazorFileChangeKind.Removed))
31+
{
32+
throw new ArgumentException("Only adds and removes are allowed", nameof(items));
33+
}
34+
}
35+
36+
instance._workQueue.AddWork(items);
37+
}
38+
39+
public Task WaitUntilCurrentBatchCompletesAsync()
40+
{
41+
return instance._workQueue.WaitUntilCurrentBatchCompletesAsync();
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)