Always try to use cached data for import completion even if outdated#59760
Always try to use cached data for import completion even if outdated#59760genlu merged 22 commits intodotnet:mainfrom
Conversation
Even if it might be stale. the completion list would be computed with cached data and cache refresh would be done in background.
Even if it might be stale. the completion list would be computed with cached data and cache refresh would be done in background.
…pletion is triggered
...e/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs
Outdated
Show resolved
Hide resolved
...ortable/Completion/Providers/ImportCompletionProvider/AbstractTypeImportCompletionService.cs
Outdated
Show resolved
Hide resolved
| var referencedProjects = graph.GetProjectsThatThisProjectTransitivelyDependsOn(currentProject.Id).SelectAsArray(id => solution.GetRequiredProject(id)); | ||
| var referencedProjects = graph.GetProjectsThatThisProjectTransitivelyDependsOn(currentProject.Id).Select(id => solution.GetRequiredProject(id)).Where(p => p.SupportsCompilation); | ||
|
|
||
| projectsBuilder.Add(currentProject); |
There was a problem hiding this comment.
Note that we no longer have any special treatment for current project, i.e. we return whatever in the cache, or if the cache isn't ready, we don't return anything from it.
|
Checking. |
| { | ||
| // Trigger a backgound task to warm up cache and return immediately. | ||
| // This won't cause multiple cache update to run simultaneously because WarmUpCacheAsync is implemented by AsyncBatchingWorkQueue. | ||
| _ = Task.Run(() => WarmUpCacheAsync(document)); |
There was a problem hiding this comment.
You shouldn't need the Task.Run. You shoudl just add an item to the work queue.
| return Task.CompletedTask; | ||
|
|
||
| _workQueue.AddWork(project.Id); | ||
| return _workQueue.WaitUntilCurrentBatchCompletesAsync(); |
There was a problem hiding this comment.
you definitely don't want to wait on the work to complete :) that somewhat defeats the purpose. you just want to put the item in the queue and then know that it will be taken care of later.
There was a problem hiding this comment.
This is the code path that returns the cache update task, not the code path for completion. That said, this can definitely use a little cleanup to make things clearer. Will update
There was a problem hiding this comment.
could you point me to the code that looks at the return value of this method?
|
|
||
| static bool HasGlobalAlias(MetadataReference? metadataReference) | ||
| => metadataReference != null && (metadataReference.Properties.Aliases.IsEmpty || metadataReference.Properties.Aliases.Any(alias => alias == MetadataReferenceProperties.GlobalAlias)); | ||
| return (resultBuilder.ToImmutable(), isPartialResult); |
There was a problem hiding this comment.
just curious what you do with isPArtialResult on the consumption side.
...ortable/Completion/Providers/ImportCompletionProvider/AbstractTypeImportCompletionService.cs
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| private static bool HasGlobalAlias(ImmutableArray<string> aliases) | ||
| => aliases.IsEmpty || aliases.Any(alias => alias == MetadataReferenceProperties.GlobalAlias); |
There was a problem hiding this comment.
this needs doc'ing. why does 'aliases.IsEmpty' imply you have global aliases?
| foreach (var peReference in GetAllRelevantPeReferences(project)) | ||
| await SymbolTreeInfo.GetInfoForMetadataReferenceAsync(project.Solution, peReference, loadOnly: false, cancellationToken).ConfigureAwait(false); | ||
| } | ||
| } |
There was a problem hiding this comment.
does thsi run in oop? or in VS? If in OOP, i'm ok with this running in parallel over all the PERefs. Unless you want it serial? (i can see args both ways).
There was a problem hiding this comment.
This is in OOP (if enabled, that is)
...ortCompletionProvider/ExtensionMethodImportCompletionHelper.ExtensionMethodSymbolComputer.cs
Outdated
Show resolved
Hide resolved
...ortable/Completion/Providers/ImportCompletionProvider/AbstractTypeImportCompletionService.cs
Outdated
Show resolved
Hide resolved
src/Tools/ExternalAccess/OmniSharp/Completion/OmniSharpCompletionOptions.cs
Outdated
Show resolved
Hide resolved
...letion/Providers/ImportCompletionProvider/AbstractExtensionMethodImportCompletionProvider.cs
Outdated
Show resolved
Hide resolved
...rtable/Completion/Providers/ImportCompletionProvider/AbstractTypeImportCompletionProvider.cs
Outdated
Show resolved
Hide resolved
src/Tools/ExternalAccess/OmniSharp/Completion/OmniSharpCompletionOptions.cs
Outdated
Show resolved
Hide resolved
…ionOptions.cs Co-authored-by: Sam Harwell <sam@tunnelvisionlabs.com>
|
|
||
| IDictionary<ProjectId, TProject> ProjectItemsCache { get; } | ||
|
|
||
| CancellationToken DisposalToken { get; } |
There was a problem hiding this comment.
All the change in the last commits are refactoring except this and its implementation.
| TimeSpan.FromSeconds(1), | ||
| BatchUpdateCacheAsync, | ||
| listener, | ||
| CacheService.DisposalToken); |
| TimeSpan.FromSeconds(1), | ||
| BatchUpdateCacheAsync, | ||
| listenerProvider.GetListener(FeatureAttribute.CompletionSet), | ||
| cacheService.DisposalToken); |
| // This is the implementation at Editor layer to provide a CancellationToken | ||
| // for the workqueue used for background cache refresh. | ||
| [ExportWorkspaceServiceFactory(typeof(IImportCompletionCacheService<ExtensionMethodImportCompletionCacheEntry, object>), ServiceLayer.Editor), Shared] | ||
| internal sealed class EditorExtensionMethodImportCompletionCacheServiceFactory |
| { | ||
| // This is the implementation at Editor layer to provide a CancellationToken | ||
| // for the workqueue used for background cache refresh. | ||
| [ExportWorkspaceServiceFactory(typeof(IImportCompletionCacheService<TypeImportCompletionCacheEntry, TypeImportCompletionCacheEntry>), ServiceLayer.Editor), Shared] |
|
Hey @CyrusNajmabadi, another look at this please? |
...e/IntelliSense/ImportCompletionCacheService/EditorTypeImportCompletionCacheServiceFactory.cs
Outdated
Show resolved
Hide resolved
...n/Providers/ImportCompletionProvider/ExtensionMethodImportCompletionHelper.SymbolComputer.cs
Outdated
Show resolved
Hide resolved
| } | ||
| } | ||
|
|
||
| public class Builder : IDisposable |
There was a problem hiding this comment.
do you pass your builders around? you coudl consider these being structs too. if you do pass it around, yuo will need to pass by ref given the mutable publicItemCount.
| var exportProvider = (IMefHostExportProvider)project.Solution.Workspace.Services.HostServices; | ||
| var listenerProvider = exportProvider.GetExports<AsynchronousOperationListenerProvider>().Single().Value; |
There was a problem hiding this comment.
📝 Code shouldn't assume HostServices implements IMefHostExportProvider. Can we not pass the listener to the constructor of this type?
There was a problem hiding this comment.
You are commenting on an out-of-date snapshot, this is moved to https://github.com/dotnet/roslyn/pull/59760/files#diff-91071542ca3996ad4d7178bc276d40deaae3e2a3b7522531f29d869e1fb636ccR48
That said, I'm still using the same code to fet listener provider there. I assume I can still import the provider in the constructor safely?
Dismissed since original concern (as well as subsequent comments) have been addressed
And refresh cache in background.