Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Fix wrong behaviour when move multiple files out of watched folder on mac #41963

Merged
merged 14 commits into from
Nov 4, 2019

Conversation

aik-jahoda
Copy link

On mac when the file is moved fsevents trigger two events. One for the original filename the second for the new filename. The events are paired and in .net FileSystemWatcher and triggered as one Rename event. When the file is moved outside the watched folder only one event with the old file name is triggered. It works fine until only one file is moved however when more files are moved outside of the directory the event for each files are paired together altought it doesn't belong to the same file.

The fix add event id constraint to match the events correctly. Tests for all platforms were added.

Fixes #41080 and Fixes #41465

Jan Jahoda added 5 commits October 16, 2019 11:16
FS
watcher
…o jahoda-filewatcher

# Conflicts:
#	src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Directory.Move.cs
@dnfclas
Copy link

dnfclas commented Oct 21, 2019

CLA assistant check
All CLA requirements met.

return null;

var currentEvent = (flags: flags[currentIndex], id: ids[currentIndex]);
var nextEvent = (flags: flags[nextIndex], id: ids[nextIndex]);
Copy link
Member

Choose a reason for hiding this comment

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

Why are these tuples helpful here? It'd be clearer IMO (and less expensive) to just do:

if (ids[currentIndex] + 1 == ids[nextIndex] &&
    IsFlagSet(flags[nextIndex], FSEventStreamEventFlags.kFSEventStreamEventFlagItemRenamed))
{
    return nextIndex;
}

currentEvent.flags isn't used anywhere, either.

Copy link
Author

Choose a reason for hiding this comment

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

The idea was to reduce index mistake by correctly name the specific event. I was about to pass the currentEvent as an argument for the FindRenameChangePairedChange, but I consider this as unnecessary refactoring of the ProcessEvents method (it was refactored a lot anyway). I accepted your proposal.

[InlineData(3)]
public void Directory_Move_Multiple_From_Watched_To_Unwatched_Mac(int filesCount)
{
DirectoryMove_Multiple_FromWatchedToUnwatched(filesCount, true);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: please name Boolean args, e.g. skipOldEvents: true

Copy link
Member

Choose a reason for hiding this comment

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

Since this is platform dependent, can we handle skipOldEvents inside the helper instead of passing it in?

Copy link
Author

Choose a reason for hiding this comment

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

The helper is quite complex and besides this filter it is the same for all platforms. I actually don't like the concept of those filters as the test is just calling a method. Instead the test should do the test itself.

My proposal there is:

testcase()
{
    // the collectEvents method is platform independent and don't care about test at all. It perform file changes and transform events to data.
    var collectedEvents = CollectEvents_Move_Multiple_FromWatchedToUnwatched(filesCount);
    // this is tricky as we don't know file names used in CollectEvents method. Maybe CollectEvents can return those names.
    var expectedEvents = ...

    // Finally the test do the test
    Assert.Equals(collectedEvents, expectedEvents)
}

or with more separation which I actually like more it would be:

testcase()
{
    var filesToMove = getFileOperations(filesCount)

    var collectedEvents = CollectEvents_Move_Multiple_FromWatchedToUnwatched(filesToMove);
    
    var expectedEvents = exctract from filesToMove

    // Finally the test do the test
    Assert.Equals(collectedEvents, expectedEvents)
}

However, both are far away from what is in the test now. I would consider a new ticket for such a change which can cover and simplified current tests.

[InlineData(3)]
public void Directory_Move_Multiple_From_Watched_To_Unwatched_Mac(int filesCount)
{
DirectoryMove_Multiple_FromWatchedToUnwatched(filesCount, true);
Copy link
Member

Choose a reason for hiding this comment

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

Since this is platform dependent, can we handle skipOldEvents inside the helper instead of passing it in?

# Conflicts:
#	src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs
@aik-jahoda aik-jahoda marked this pull request as ready for review October 25, 2019 15:46
Co-Authored-By: Cory Nelson <phrosty@gmail.com>
alexischr added a commit to mono/mono that referenced this pull request Dec 2, 2019
alexischr added a commit to mono/mono that referenced this pull request Dec 9, 2019
alexischr pushed a commit to mono/corefx that referenced this pull request Dec 17, 2019
alexischr pushed a commit to mono/corefx that referenced this pull request Dec 17, 2019
alexischr added a commit to mono/mono that referenced this pull request Dec 17, 2019
…of watched folder on mac (#41963)

Backport of Backport of dotnet/corefx#41963

Fixes #16778
alexischr added a commit to mono/mono that referenced this pull request Dec 17, 2019
@karelz karelz added this to the 5.0 milestone Dec 19, 2019
alexischr added a commit to mono/mono that referenced this pull request Dec 31, 2019
alexischr added a commit to mono/mono that referenced this pull request Dec 31, 2019
…of watched folder on mac (#41963)

Backport of Backport of dotnet/corefx#41963

Fixes #16778
alexischr added a commit to mono/mono that referenced this pull request Jan 6, 2020
lambdageek pushed a commit to mono/mono that referenced this pull request Jan 6, 2020
alexischr added a commit to mono/mono that referenced this pull request Jan 7, 2020
alexischr added a commit to mono/mono that referenced this pull request Jan 9, 2020
@optimizasean
Copy link

It appears this issue is still present in macOS Catalina. I am having this issue now, the dotnet watch command does not work for me. It cannot detect when I save a file (changes or not), when I delete a file, when I add a file, when I move a file, or anything really including changes through terminal and git and vscode and the finder itself. Basically non-responsive to anything from as far as I can tell. Is there a definitive fix in motion for this? It is quite the frustrating bug since I used the file watcher a lot when I was on Mojave. Not having it is very inconvenient.

Running Catalina + .NET 6.0 preview 2

@danmoseley
Copy link
Member

@optimizasean if you're seeing an issue please open an issue in the dotnet/runtime repo. It would be good if you could also share whether it works on 5.0

@optimizasean
Copy link

@danmoseley, I am not sure if it is an issue, I have seen a few messages in the aspnet gitter but I think it might be an isolated problem, not an issue. I hope if someone else has the same problem, they will google and find it here and then we will be able to tell if it is an issue or a problem with my system. As for 5.X it worked with Mojave through 3.X-5.X. At 6p2, it worked on Mojave but once I moved to Catalina, it stopped working.

@optimizasean
Copy link

optimizasean commented Jun 22, 2021

I am not sure if it is isolated. I was working fine on Mojave .NET core 3 to .NET5 full release, then moved to Catalina and broken. Moved to fresh new mac on Catalina and it also doesn't work here, since .NET6p2 all the way to .NET6p5 (current).

I have tried all variants of the watch command using absolute and relative path, project v.s. solution, as well as the different delimiters like -- run and more on .NET6p5. Have exhausted every combination. It does not detect additions, deletions, or changes in files: .css .razor .cs, even the Program or Startup files. It does not detect even when a file is moved, renamed, added, or deleted.

Probably separate issue: The watch command causes these two errors in browser console:

* Assertion at /__w/1/s/src/mono/mono/metadata/assembly.c:1374, condition `<disabled>' not met

542256 @ dotnet.6.0.0-preview.5.21301.5.js:1
ExitStatus
message: "Program terminated with exit(0)"
name: "ExitStatus"
status: 0
__proto__: Object

Edit:
Ahhh it appears I was here before, maybe this should be moved into an issue, looking for feedback for where to write it.

@danmoseley
Copy link
Member

danmoseley commented Jun 22, 2021

@optimizasean issues for this code should be opened in https://github.com/dotnet/runtime.

This isn't the first report of problems with the file system watcher on Mac: you may see an existing issue you can add to instead:
https://github.com/dotnet/runtime/issues?q=is%3Aissue+is%3Aopen+filesystemwatcher

It has been challenging to stabilize the FSW for Mac and we may not have time to look at this soon. If you are interested in helping figure out what's going on, the next step might be to build a private copy of the code (using contribution instructions in dotnet/runtime) and perhaps add some tracing.

Please open a separate issue there for the assert in Mono's assembly loader.

@danmoseley
Copy link
Member

(This repo only exists now to hold PR's for servicing old releases)

@optimizasean
Copy link

Thanks @danmoseley I made a request here: dotnet/runtime#54586 for all of the previous

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
… mac (dotnet/corefx#41963)

* FS

watcher

* Multiple rename macOS fix

* Multiple rename macOS fix

* Format code

* Clean proj file

* Apply PR comments

* Apply suggestions from code review

Co-Authored-By: Cory Nelson <phrosty@gmail.com>

* Update src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs

Co-Authored-By: Stephen Toub <stoub@microsoft.com>

* Apply PR comments

* Apply PR comments

* Apply PR comments

* Document rename event id behaviour


Commit migrated from dotnet/corefx@a1f8c91
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants