KEMBAR78
Utilize IVsAsyncFileChangeEx2 by ToddGrun · Pull Request #70936 · dotnet/roslyn · GitHub
Skip to content

Conversation

@ToddGrun
Copy link
Contributor

@ToddGrun ToddGrun commented Nov 22, 2023

This interface allows a more efficient mechanism by allowing for batch advising to file change events.

Fixes AB#1870752

This interface allows a more efficient mechanism by allowing for batch advising to file change events.

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1870752
@ToddGrun ToddGrun requested a review from a team as a code owner November 22, 2023 14:23
@ghost ghost added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Nov 22, 2023
@ToddGrun ToddGrun requested a review from davkean November 22, 2023 14:30
@ToddGrun
Copy link
Contributor Author

@jasonmalinowski -- are you the right person to take a look?

@jasonmalinowski
Copy link
Member

@ToddGrun I am! sorry for missing the ping here.

case Kind.WatchFiles:
var cookies = await service.AdviseFileChangesAsync(_files, _fileChangeFlags, _sink, cancellationToken).ConfigureAwait(false);

Contract.ThrowIfTrue(cookies.Length != _tokens.Length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this throws, it would mean the cookies that were returned will then be leaked. This really shouldn't happen though, but do we want to have some sort of cleanup in that case? Or at least should we really crash the process since something went very wrong?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is along the lines of something that should never happen (since we know from our code that _paths and _tokens are of the same length). If they give us back a different number of cookies that paths we sent, then they are being super bad and probably are causing issues in all callers. I think I'd like to just keep this as is unless you feel strongly.

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signing off as I think this looks fine, but there might be a nice follow-up here. Now we have four states, for Watch/Unwatch and single file versus files. But if we use something like OneOrMany to hold the single/many we can reduce down to two states and probably simplify the code a bit further. I'll leave it to you to decide if that's worth doing now (or not.)

Comment on lines +305 to +306
switch (op._kind)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What worries me most with this is whether we'd accidentally forget to include one of the fields in one of the branches, meaning a combining might drop something. Is there any reason we can't do something like just checking _token for whether there is one, or just adding _tokens (which will be empty and probably a no-op)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't clear on the ask here, are you still wanting this change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my worry would be if one of the branches here forgot to add something to a builder -- it'd mean that an operation would work fine by itself, but once we merged it something might get lost.

My thought though: do we need the switch? Because if you just took the code in the WatchFiles branch (which also covers Unwatch files) and the UnwatchDirectories, does it just work for all scenarios?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I'd want to merge these codepaths. One concern is that some of these fields could be null (eg, op.__cookies can be null). It's not a lot of code, and I think it makes it clearer if they are separated.

@ToddGrun
Copy link
Contributor Author

ToddGrun commented Dec 4, 2023

@jasonmalinowski -- would love to get your eyes on this again since I changed it a bit from the last time you looked. Thanks!

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Comment on lines +305 to +306
switch (op._kind)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my worry would be if one of the branches here forgot to add something to a builder -- it'd mean that an operation would work fine by itself, but once we merged it something might get lost.

My thought though: do we need the switch? Because if you just took the code in the WatchFiles branch (which also covers Unwatch files) and the UnwatchDirectories, does it just work for all scenarios?

1) simplify CanCombineWith
2) Use ArrayBuilder.Add instead of AddRange
3) Verify collection count before access
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants