-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always try to use cached data for import completion even if outdated #59760
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
@@ -47,6 +48,9 @@ public override async Task ProvideCompletionsAsync(CompletionContext completionC | |||
var syntaxContext = await CreateContextAsync(document, completionContext.Position, cancellationToken).ConfigureAwait(false); | |||
if (!ShouldProvideCompletion(completionContext, syntaxContext)) | |||
{ | |||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs doc'ing. why does 'aliases.IsEmpty' imply you have global aliases?
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing async tracking
...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 <[email protected]>
{ | ||
internal interface IImportCompletionCacheService<TProject, TPortableExecutable> : IWorkspaceService | ||
{ | ||
// PE references are keyed on assembly path. | ||
IDictionary<string, TPortableExecutable> PEItemsCache { get; } | ||
|
||
IDictionary<ProjectId, TProject> ProjectItemsCache { get; } | ||
|
||
CancellationToken DisposalToken { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the change in the last commits are refactoring except this and its implementation.
TimeSpan.FromSeconds(1), | ||
BatchUpdateCacheAsync, | ||
listener, | ||
CacheService.DisposalToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use token for workqueue
TimeSpan.FromSeconds(1), | ||
BatchUpdateCacheAsync, | ||
listenerProvider.GetListener(FeatureAttribute.CompletionSet), | ||
cacheService.DisposalToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use token for workqueue
// 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new Editor layer factory
{ | ||
// 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] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new Editor layer factory
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Dismissed since original concern (as well as subsequent comments) have been addressed
And refresh cache in background.