-
Notifications
You must be signed in to change notification settings - Fork 133
Remove all references to dropped modules and force GC on reload #1402
Changes from all commits
521eb47
74dec25
6abeb90
ddfb305
bfc4955
2425d1e
e843a60
30bd001
0336dfb
4c51603
fbed27b
540676f
490991b
ac2bb01
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,6 @@ | |
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Python.Analysis.Caching; | ||
|
@@ -49,6 +48,7 @@ public sealed class PythonAnalyzer : IPythonAnalyzer, IDisposable { | |
private int _version; | ||
private PythonAnalyzerSession _currentSession; | ||
private PythonAnalyzerSession _nextSession; | ||
private bool _forceGCOnNextSession; | ||
|
||
public PythonAnalyzer(IServiceManager services, string cacheFolderPath = null) { | ||
_services = services; | ||
|
@@ -196,16 +196,27 @@ public IReadOnlyList<DiagnosticsEntry> LintModule(IPythonModule module) { | |
return optionsProvider?.Options?.LintingEnabled == false ? Array.Empty<DiagnosticsEntry>() : result; | ||
} | ||
|
||
public void ResetAnalyzer() { | ||
public async Task ResetAnalyzer() { | ||
var interpreter = _services.GetService<IPythonInterpreter>(); | ||
var builtins = interpreter.ModuleResolution.BuiltinsModule; | ||
builtins.SetAst(builtins.Analysis.Ast); | ||
|
||
await interpreter.TypeshedResolution.ReloadAsync(); | ||
await interpreter.ModuleResolution.ReloadAsync(); | ||
|
||
lock (_syncObj) { | ||
_analysisEntries.Split(kvp => kvp.Key.IsTypeshed || kvp.Value.Module is IBuiltinsPythonModule, out var entriesToPreserve, out var entriesToRemove); | ||
_forceGCOnNextSession = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we reload There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sort of; the way we create the builtins module is really contrived and currently can only be created once when the interpreter object is created. What I had to do here is only a partial fix; we don't have a way to do a complete reload including the builtin module, so I kept the existing code and allowed it to remove more. I'd like for this to be fixed in the future so we can have a "real" reload that drops everything but file contents and does a complete restart, but I think that'd be a bigger change. |
||
|
||
_analysisEntries.Split(kvp => kvp.Value.Module is IBuiltinsPythonModule, out var entriesToPreserve, out var entriesToRemove); | ||
_analysisEntries.Clear(); | ||
foreach (var (key, entry) in entriesToPreserve) { | ||
_analysisEntries.Add(key, entry); | ||
} | ||
|
||
_dependencyResolver.RemoveKeys(entriesToRemove.Select(e => e.Key)); | ||
} | ||
|
||
_services.GetService<IRunningDocumentTable>().ReloadAll(); | ||
} | ||
|
||
public IReadOnlyList<IPythonModule> LoadedModules { | ||
|
@@ -218,7 +229,7 @@ public IReadOnlyList<IPythonModule> LoadedModules { | |
|
||
public event EventHandler<AnalysisCompleteEventArgs> AnalysisComplete; | ||
|
||
internal void RaiseAnalysisComplete(int moduleCount, double msElapsed) | ||
internal void RaiseAnalysisComplete(int moduleCount, double msElapsed) | ||
=> AnalysisComplete?.Invoke(this, new AnalysisCompleteEventArgs(moduleCount, msElapsed)); | ||
|
||
private void AnalyzeDocument(in AnalysisModuleKey key, in PythonAnalyzerEntry entry, in ImmutableArray<AnalysisModuleKey> dependencies) { | ||
|
@@ -241,7 +252,7 @@ private void AnalyzeDocument(in AnalysisModuleKey key, in PythonAnalyzerEntry en | |
session.Start(true); | ||
} | ||
} | ||
|
||
private bool TryCreateSession(in int graphVersion, in PythonAnalyzerEntry entry, out PythonAnalyzerSession session) { | ||
var analyzeUserModuleOutOfOrder = false; | ||
lock (_syncObj) { | ||
|
@@ -276,7 +287,7 @@ private bool TryCreateSession(in int graphVersion, in PythonAnalyzerEntry entry, | |
session = null; | ||
return false; | ||
} | ||
|
||
if (_currentSession.IsCompleted) { | ||
_currentSession = session = CreateSession(walker, null); | ||
return true; | ||
|
@@ -301,14 +312,21 @@ private void StartNextSession(Task task) { | |
session.Start(false); | ||
} | ||
|
||
private PythonAnalyzerSession CreateSession(in IDependencyChainWalker<AnalysisModuleKey, PythonAnalyzerEntry> walker, in PythonAnalyzerEntry entry) | ||
=> new PythonAnalyzerSession(_services, _progress, _analysisCompleteEvent, _startNextSession, _disposeToken.CancellationToken, walker, _version, entry); | ||
private PythonAnalyzerSession CreateSession(in IDependencyChainWalker<AnalysisModuleKey, PythonAnalyzerEntry> walker, in PythonAnalyzerEntry entry) { | ||
bool forceGC; | ||
lock (_syncObj) { | ||
forceGC = _forceGCOnNextSession; | ||
_forceGCOnNextSession = false; | ||
} | ||
|
||
return new PythonAnalyzerSession(_services, _progress, _analysisCompleteEvent, _startNextSession, _disposeToken.CancellationToken, walker, _version, entry, forceGC: forceGC); | ||
} | ||
|
||
private void LoadMissingDocuments(IPythonInterpreter interpreter, ImmutableArray<AnalysisModuleKey> missingKeys) { | ||
if (missingKeys.Count == 0) { | ||
return; | ||
} | ||
|
||
var foundKeys = ImmutableArray<AnalysisModuleKey>.Empty; | ||
foreach (var missingKey in missingKeys) { | ||
lock (_syncObj) { | ||
|
Uh oh!
There was an error while loading. Please reload this page.