Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit b1e5f31

Browse files
author
MikhailArkhipov
committed
Speed up CancelAnalysis
1 parent 17b9830 commit b1e5f31

6 files changed

Lines changed: 19 additions & 10 deletions

File tree

src/Analysis/Engine/Impl/Deque.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ public void AppendLeft(T x) {
8282
}
8383

8484
public void Clear() {
85-
AssertScope();
86-
8785
_version++;
8886

8987
_head = _tail = 0;

src/Analysis/Engine/Impl/Intellisense/AnalysisQueue.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ internal sealed class AnalysisQueue : IDisposable {
3131
private static readonly AsyncLocal<AnalysisQueue> _current = new AsyncLocal<AnalysisQueue>();
3232
public static AnalysisQueue Current => _current.Value;
3333

34+
private readonly DisposeToken _disposeToken = DisposeToken.Create<AnalysisQueue>();
3435
private readonly HashSet<IGroupableAnalysisProject> _enqueuedGroups;
3536
private readonly PriorityProducerConsumer<QueueItem> _ppc;
3637
private readonly Task _consumerTask;
@@ -160,6 +161,7 @@ public void Dispose() {
160161
Trace.TraceWarning("Failed to wait for worker thread to terminate");
161162
}
162163
}
164+
_disposeToken.TryMarkDisposed();
163165
}
164166

165167
private struct QueueItem {

src/Analysis/Engine/Impl/PythonAnalyzer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ public void Dispose() {
985985

986986
protected virtual void Dispose(bool disposing) {
987987
if (disposing) {
988+
Queue.Clear();
988989
IDisposable interpreter = _interpreter as IDisposable;
989990
if (_disposeInterpreter && interpreter != null) {
990991
interpreter.Dispose();

src/Analysis/Engine/Test/AnalysisTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5341,7 +5341,7 @@ public async Task CancelAnalysis() {
53415341

53425342
var files = Directory.GetFiles(Path.Combine(configuration.PrefixPath, "Lib"), "*.py", SearchOption.AllDirectories);
53435343
Trace.TraceInformation($"Files count: {files}");
5344-
var contentTasks = files.Select(f => File.ReadAllTextAsync(f)).ToArray();
5344+
var contentTasks = files.Take(Math.Min(50, files.Length)).Select(f => File.ReadAllTextAsync(f)).ToArray();
53455345

53465346
await Task.WhenAll(contentTasks);
53475347

@@ -5350,15 +5350,15 @@ public async Task CancelAnalysis() {
53505350
var analysisCompleteTask = Task.CompletedTask;
53515351
try {
53525352
server = await CreateServerAsync(configuration);
5353-
for (var i = 0; i < files.Length && server.AnalysisQueue.Count < 50; i++) {
5353+
for (var i = 0; i < contentTasks.Length && server.AnalysisQueue.Count < 50; i++) {
53545354
await server.SendDidOpenTextDocument(new Uri(files[i]), contentTasks[i].Result);
53555355
}
53565356

53575357
server.AnalysisQueue.Count.Should().NotBe(0);
53585358
} finally {
53595359
if (server != null) {
53605360
analysisCompleteTask = EventTaskSources.AnalysisQueue.AnalysisComplete.Create(server.AnalysisQueue, new CancellationTokenSource(10000).Token);
5361-
serverDisposeTask = Task.WhenAny(Task.Run(() => server.Dispose()), Task.Delay(1000));
5361+
serverDisposeTask = Task.WhenAny(Task.Run(() => server.Dispose()), Task.Delay(5000));
53625362
}
53635363
}
53645364

src/LanguageServer/Impl/Implementation/ParseQueue.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
using Microsoft.PythonTools.Parsing.Ast;
3030

3131
namespace Microsoft.Python.LanguageServer.Implementation {
32-
class ParseQueue {
32+
class ParseQueue: IDisposable {
3333
public const string PythonParserSource = "Python (parser)";
3434
private const string TaskCommentSource = "Task comment";
3535

@@ -41,6 +41,8 @@ public ParseQueue() {
4141
_parsing = new ConcurrentDictionary<Uri, ParseTask>();
4242
}
4343

44+
public void Dispose() => _parsing.Clear();
45+
4446
public int Count => _parsingInProgress.Count;
4547

4648
public Task WaitForAllAsync() => _parsingInProgress.WaitForZeroAsync();

src/LanguageServer/Impl/Implementation/Server.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ public Server() {
9696

9797
_disposableBag
9898
.Add(ProjectFiles)
99-
.Add(() => Analyzer?.Dispose())
100-
.Add(() => _shutdownCts.Cancel())
101-
.Add(AnalysisQueue)
10299
.Add(() => {
103100
foreach (var ext in _extensions.Values) {
104101
(ext as IDisposable)?.Dispose();
@@ -121,7 +118,12 @@ private void Analysis_UnhandledException(object sender, UnhandledExceptionEventA
121118
internal ServerSettings Settings { get; private set; } = new ServerSettings();
122119
internal ProjectFiles ProjectFiles { get; } = new ProjectFiles();
123120

124-
public void Dispose() => _disposableBag.TryDispose();
121+
public void Dispose() {
122+
_shutdownCts.Cancel();
123+
AnalysisQueue.Dispose();
124+
Analyzer?.Dispose();
125+
_disposableBag.TryDispose();
126+
}
125127

126128
#region ILogger
127129
public void TraceMessage(IFormattable message) {
@@ -625,6 +627,7 @@ internal Task EnqueueItemAsync(IDocument doc, AnalysisPriority priority = Analys
625627
LogMessage(MessageType.Error, t.Exception.Message);
626628
return;
627629
}
630+
_shutdownCts.Token.ThrowIfCancellationRequested();
628631
await OnDocumentChangeProcessingCompleteAsync(doc, t.Result as VersionCookie, enqueueForAnalysis, priority, pending);
629632
});
630633
} catch {
@@ -635,6 +638,7 @@ internal Task EnqueueItemAsync(IDocument doc, AnalysisPriority priority = Analys
635638

636639
private async Task OnDocumentChangeProcessingCompleteAsync(IDocument doc, VersionCookie vc, bool enqueueForAnalysis, AnalysisPriority priority, IDisposable disposeWhenEnqueued) {
637640
try {
641+
_shutdownCts.Token.ThrowIfCancellationRequested();
638642
_disposableBag.ThrowIfDisposed();
639643
if (vc != null) {
640644
foreach (var kv in vc.GetAllParts(doc.DocumentUri)) {
@@ -645,6 +649,7 @@ private async Task OnDocumentChangeProcessingCompleteAsync(IDocument doc, Versio
645649
}
646650

647651
if (doc is IAnalyzable analyzable && enqueueForAnalysis) {
652+
_shutdownCts.Token.ThrowIfCancellationRequested();
648653
AnalysisQueued(doc.DocumentUri);
649654
AnalysisQueue.Enqueue(analyzable, priority);
650655
}
@@ -658,6 +663,7 @@ private async Task OnDocumentChangeProcessingCompleteAsync(IDocument doc, Versio
658663
if (doc is ProjectEntry entry) {
659664
var reanalyzeEntries = Analyzer.GetEntriesThatImportModule(entry.ModuleName, false);
660665
foreach (var d in reanalyzeEntries.OfType<IDocument>()) {
666+
_shutdownCts.Token.ThrowIfCancellationRequested();
661667
await EnqueueItemAsync(d, parse: false);
662668
}
663669
}

0 commit comments

Comments
 (0)